下面的示例会创建新的角色和用户:
>>> from hello import Role, User >>> 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=user_role) >>> user_david = User(username='david', role=user_role)
模型的构造函数接受模型属性的初始值作为关键字参数。注意,甚至可以使用role属性,即使它不是一个真正的数据库列,而是一对多关系的高级表示。这些新对象的id属性没有显式设置:主键由Flask-SQLAlchemy来管理。到目前为止对象只存于Python中,他们还没有被写入数据库。因为他们的id值尚未分配:
>>> print(admin_role.id) None >>> print(mod_role.id) None >>> print(user_role.id) None
修改数据库的操作由Flask-SQLAlchemy提供的db.session数据库会话来管理。准备写入到数据库中的对象必须添加到会话中:
>>> db.session.add(admin_role) >>> db.session.add(mod_role) >>> db.session.add(user_role) >>> db.session.add(user_john) >>> db.session.add(user_susan) >>> db.session.add(user_david)
或,更简洁的:
>>> db.session.add_all([admin_role, mod_role, user_role, ... user_john, user_susan, user_david])为了写对象到数据库,需要通过它的commit()方法来提交会话:
>>> db.session.commit()
再次检查id属性;这个时候它们都已经被设置好了:
>>> print(admin_role.id) 1 >>> print(mod_role.id) 2 >>> print(user_role.id) 3
注:db.session数据库会话和第四章讨论的Flask会话没有任何联系。数据库会话也叫事务。
数据库会话在数据库一致性上是非常有用的。提交操作会原子性地将所有添加到会话中的对象写入数据库。如果在写入的过程发生错误,会将整个会话丢弃。如果你总是在一个会话提交相关修改,你必须保证避免因部分更新导致的数据库不一致的情况。
注:数据库会话也可以回滚。如果调用db.session.rollback(),任何添加到数据库会话中的对象都会恢复到它们曾经在数据库中的状态。
修改行
数据库会话中的add()方法同样可以用于更新模型。继续在同一shell会话中,下面的示例重命名“Admin”角色为“Administrator”:
>>> admin_role.name = 'Administrator' >>> db.session.add(admin_role) >>> db.session.commit()
注意:不过貌似我们在做更新操作的时候都不使用db.session.add(),而是直接使用db.session.commit()来提交事务。
删除行
数据库会话同样有delete()方法。下面的示例从数据库中删除“Moderator”角色:
>>> db.session.delete(mod_role) >>> db.session.commit()
注意删除,和插入更新一样,都是在数据库会话提交后执行。
返回行
Flask-SQLAlchemy为每个模型类创建一个query对象。最基本的查询模型是返回对应的表的全部内容:
>>> Role.query.all() [<Role u'Administrator'>, <Role u'User'>] >>> User.query.all() [<User u'john'>, <User u'susan'>, <User u'david'>]
使用过滤器可以配置查询对象去执行更具体的数据库搜索。下面的例子查找所有被分配“User”角色的用户:
>>> User.query.filter_by(role=user_role).all() [<User u'susan'>, <User u'david'>]
对于给定的查询还可以检查SQLAlchemy生成的原生SQL查询,并将查询对象转换为一个字符串:
>>> str(User.query.filter_by(role=user_role)) 'SELECT users.id AS users_id, users.username AS users_username, users.role_id AS users_role_id FROM users WHERE :param_1 = users.role_id'
如果你退出shell会话,在前面的示例中创建的对象将不能作为Python对象而存在,但可继续作为行记录存在各自的数据库表中。如果你开始一个全新的shell会话,你必须从它们的数据库行中重新创建Python对象。下面的示例执行查询来加载名字为“User”的用户角色。
>>> user_role = Role.query.filter_by(name='User').first()
过滤器如filter_by()通过query对象来调用,且返回经过提炼后的query。多个过滤器可以依次调用直到需要的查询配置结束为止。
下面展示一些查询中常用的过滤器。
在需要的过滤器已经全部运用于query后,调用all()会触发query执行并返回一组结果,但是除了all()以外还有其他方式可以触发执行。常用SQLAlchemy查询执行器:
关系的原理类似于查询。下面的示例从两边查询角色和用户之间的一对多关系:
>>> users = user_role.users >>> users [<User u'susan'>, <User u'david'>] >>> users[0].role <Role u'User'>
此处的user_role.users查询有点小问题。当user_role.users表达式在内部调用all()时通过隐式查询执行来返回用户的列表。因为查询对象是隐藏的,是不可能通过附加查询过滤器进一步提取出来。在这个特定的例子中,它可能是用于按字母排列顺序返回用户列表。在下面的示例中,被lazy = 'dynamic'参数修改过的关系配置的查询是不会自动执行的。
app/models.py:动态关系
class Role(db.Model): # ... users = db.relationship('User', backref='role', lazy='dynamic') # ...
用这种方式配置关系,user_roles.user查询还没有执行,所以可以给它增加过滤器:
>>> user_role.users.order_by(User.username).all() [<User u'david'>, <User u'susan'>] >>> user_role.users.count() 2
标签:SQLite
相关阅读 >>
rxjava2_flowable_Sqlite_android数据库访问实例
c#操作Sqlite数据库方法小结(创建,连接,插入,查询,删除等)
Sqlite developer怎么安装激活 Sqlite developer激活安装图文教程
基于java实现一个简单的单词本android app的实践
更多相关阅读请进入《Sqlite》频道 >>
数据库系统概念 第6版
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。