模型的构造函数,接收的参数是使用关键字参数指定的模型属性初始值。注意,role 属性也可使用,虽然他不是真正的数据库列,但却是一对多关系的高级表示。这些新建对象的 id 属性并没有明确设定,因为主键是由 Flask-SQLAlchemy 管理的。现在这些对象只存在于 Python 解释器中,尚未写入数据库。
>> from myflask import db, User, Role >> db.create_all() >> admin_role = Role(name="Admin") >> mod_role = Role(name="Moderator") >> user_role = Role(name="User") >> user_john = User(username="john", role=admin_role) >> user_susan = User(username="susan", role=mod_role) >> user_david = User(username="david", role=user_role) >> admin_role.name 'Admin' >> admin_role.id None --------- >> db.session.add_all([admin_role, mod_role, user_role, user_john, user_susan, user_david]) # 把对象添加到会话中. >> db.session.commit() # 把对象写入数据库, 使用 commit() 提交会话.
(3)修改行
>> admin_role = "Administrator" >> db.session.add(admin_role) >> db.session.commit()
(4)删除行
>> db.session.delete(mod_role) >> db.session.commit()
(5)查询行
Flask-SQLAlchemy 为每个模型类都提供了 query 对象.
获取表中的所有记录
>> Role.query.all() [<Role u'Admin'>, <Role u'Moderator'>, <Role u'User'>] >> User.query.all() [<Role u'john'>, <Role u'susan'>, <Role u'david'>]
查询过滤器
filter_by() 等过滤器在 query 对象上调用, 返回一个更精确的 query 对象. 多个过滤器可以一起调用, 直到获取到所需的结果.
>> User.query.filter_by(role=user_role).all() # 以列表形式,返回所有结果, >> User.query.filter_by(role=user_role).first() # 返回结果中的第一个.
filter() 对查询结果过滤,比”filter_by()”方法更强大,参数是布尔表达式
# WHERE age<20 users = User.query.filter(User.age<20) # WHERE name LIKE 'J%' AND age<20 users = User.query.filter(User.name.startswith('J'), User.age<20)
查询过滤器 :
查询执行函数 :
first_or_404() | 返回查询的第一个结果,如果没有结果,则终止请求,返回 404 错误响应 | |
| get() | 返回指定主键对应的行,如果没有对应的行,则返回 None |
get_or_404() | 返回指定主键对应的行,如果没找到指定的主键,则终止请求,返回 404 | |错误响应
| count() | 返回查询结果的数量 |
| paginate() | 返回一个 Paginate 对象,它包含指定范围内的结果 |
(6)会话管理,事务管理
单个提交
>> db.session.add(ONE) >> db.session.commit()
多个提交
>> db.session.add_all([LIST_OF_MEMBER]) >> db.session.commit()
删除会话
>> db.session.delete(mod_role) >> db.session.commit()
事务回滚 : 添加到数据库会话中的所有对象都会还原到他们在数据库时的状态.
>> db.session.rollback()
七、视图函数中操作数据库
@app.route('/', methods=['GET', 'POST']) def index(): form = NameForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.name.data).first() if user is None: user = User(username=form.name.data) db.session.add(user) session["known"] = False else: session["known"] = True session["name"] = form.name.data form.name.data = "" # why empty it ? return redirect(url_for("index")) return render_template("index.html", current_time=datetime.utcnow(), form=form, name=session.get("name"), known=session.get("known"))
八、分页对象 Pagination
1. paginate() 方法
paginate() 方法的返回值是一个 Pagination 类对象,该类在 Flask-SQLAlchemy 中定义,用于在模板中生成分页链接。
paginate(页数[,per_page=20, error_out=True]) 页数 : 唯一必须指定的参数, per_page : 指定每页现实的记录数量, 默认 20. error_out : True 如果请求的页数超出了返回, 返回 404 错误; False 页数超出范围时返回一个,空列表.
示例代码:
@main.route("/", methods=["GET", "POST"]) def index(): # ... page = request.args.get('page', 1, type=int) # 渲染的页数, 默认第一页, type=int 保证参数无法转换成整数时, 返回默认值. pagination = Post.query.order_by(Post.timestamp.desc()).paginate(page, per_page=current_app.config ["FLASKY_POSTS_PER_PAGE"], error_out=False) posts = pagination.items return render_template('index.html', form=form, posts=posts,pagination=pagination)
2. 分页对象的属性及方法:
Flask_SQLAlchemy 分页对象的属性:
在分页对象可调用的方法:
3. 在模板中与 BootStrap 结合使用示例
使用 Flaks-SQLAlchemy 的分页对象与 Bootstrap 中的分页 CSS, 可以轻松的构造出一个 分页导航.
分页模板宏 _macros.html : 创建一个 Bootstrap 分页元素, 即一个有特殊样式的无序列表.
{% macro pagination_widget(pagination,endpoint) %} <ul class="pagination"> <li {% if not pagination.has_prev %} class="disabled" {% endif %}> <a href="{% if pagination.has_prev %}{{url_for(endpoint, page=paginatin.page - 1, **kwargs)}}{% else %} #{% endif %}"> « </a> </li> {% for p in pagination,.iter_pages() %} {% if p %} {% if p == pagination.page %} <li class="active"> <a rel="external nofollow" >{{p}}</a> </li> {% else %} <li> <a rel="external nofollow" >{{p}}</a> </li> {% endif %} {% else %} <li class="disabled"><a rel="external nofollow" >…</a> </li> {% endif %} {% endfor %} <li {% if not pagination.has_next %} class="disabled" {% endif%}> <a href="{% if paginatin.has_next %}{{ url_for(endpoint, page=pagination.page+1, **kwargs) }}{% else %} #{% endif %}"> » </a> </li> </ul> {% endmacro %}
导入使用分页导航
{% extends "base.html" %} {% import "_macros.html" as macros %} ... <div class="pagination"> {{ macro.pagination_widget(pagination, ".index")}} </div>
九、监听事件
1. set 事件
示例代码 :
from markdown import markdown import bleach class Post(db.Model): # ... body = db.Colume(db.Text) body_html = db.Column(db.Text) # ... @staticmethod def on_changeed_body(target, value, oldvalue, initiator): allowed_tags = ["a", "abbr", "acronym", "b", "blockquote", "code", "em", "i", "li", "ol", "pre", "strong", "ul", "h1", "h2","h3","h4","p"] target.body_html = bleach.linkify(bleach.clean(markdown(value, output_format="html"), tags=allowed_tags, strip=True)) db.event.listen(Post.body, "set", Post.on_changeed_body) # on_changed_body 函数注册在 body 字段上, 是 SQLIAlchemy "set" 事件的监听程序, # 这意味着只要这个类实例的 body 字段设了新值, 函数就会自动被调用. # on_changed_body 函数把 body 字段中的文本渲染成 HTML 格式, # 结果保存在 body_html 中, 自动高效的完成 Markdown 文本到 HTML 的转换
十、记录慢查询
十一、Binds 操作多个数据库
十二、其他
1. ORM 在查询时做初始化操作
当 SQLIAlchemy ORM 从数据库查询数据时, 默认不调用__init__ 方法, 其底层实现了 Python 类的 __new__() 方法, 直接实现 对象实例化, 而不是通过 __init__ 来实例化对象.
如果需要在查询时, 依旧希望实现一些初始化操作, 可以使用 orm.reconstructor() 装饰器或 实现 InstanceEvents.load() 监听事件。
# orm.reconstructor from sqlalchemy import orm class MyMappedClass(object): def __init__(self, data): self.data = data # we need stuff on all instances, but not in the database. self.stuff = [] @orm.reconstructor def init_on_load(self): self.stuff = [] # InstanceEvents.load() from sqlalchemy import event ## standard decorator style @event.listens_for(SomeClass, 'load') def receive_load(target, context): "listen for the 'load' event" # ... (event handling logic) ...
如果只是希望在从数据库查询生成的对象中包含某些属性, 也可以使用 property 实现:
class AwsRegions(db.Model): name=db.Column(db.String(64)) ... @property def zabbix_api(self): return ZabbixObj(zabbix_url) @zabbix_api.setter def zabbix_api(self): raise ValueError("zabbix can not be setted!")
到此这篇关于Flask中sqlalchemy模块的实例用法的文章就介绍到这了,更多相关Flask中sqlalchemy模块的使用内容请搜索
标签:SQLite
相关阅读 >>
from csv to Sqlite3 by python 导入csv到Sqlite实例
scp远程vps快速搬家和wdcp升级php5.3安装memcached和eaccelerator教程
android实现搜索功能并将搜索结果保存到Sqlite中(实例代码)
更多相关阅读请进入《Sqlite》频道 >>

数据库系统概念 第6版
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。