sqlalchemy文档资料翻译(四)

[程序]sqlalchemy文档资料翻译(四) -- 添加新对象

英文原文链接地址

为了持久化我们的 User 对象,我们通过 add() 方法将其添加到Session 中:

>>> ed_user = User('ed', 'Ed Jones', 'edspassword')
>>> session.add(ed_user)

此时,该实例处于待处理状态,并不会生成任何的 SQL 代码。 Session 会在需要的时候通过一种名为 flush 的方法通过生成 SQL 语句来持久化该对象。如果此时我们在数据库中查询Ed Jones,所有待处理信息将会首先被刷新,之后再生成查询。

例如,接下来我们将创建一个读取 User 实例的查询。我们通过 name 属性为 ed 的来过滤,并返回结果集中第一个对象。此时会返回一个等同于我们之前添加的User 实例:

>>> our_user = session.query(User).filter_by(name='ed').first()

BEGIN
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('ed', 'Ed Jones', 'edspassword')
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
FROM users
WHERE users.name = ?
LIMIT 1 OFFSET 0
('ed',)

>>> our_user
<User('ed','Ed Jones','edspassword')>

实际上,Session 确认查询返回的对象和其内部对象映射中的某对象一致,因此我们实际查询得到的对象和我们刚才添加的完全一致:

>>> ed_user is our_user
True

此处用到的被称为恒等映射的 ORM 机制确保了所有作用于数据库中的操作同时也会在 Session 中对应的数据中产生影响。一旦拥有特定主键的对象出现在Session 中,所有在该 Session 上的对于该主键的 SQL 查询将会返回同一个 Python 对象;当我们此时尝试在该 Session 中添加一个已经持久化的同主键的第二个对象时,将会产生一个error。

我们可以通过使用 add_all() 方法来创建更多的 User 对象:

>>> session.add_all([
...     User('wendy','Wendy Williams', 'foobar'),
...     User('mary','Mary Contrary', 'xxg527'),
...     User('fred','Fred Flinstone', 'blah')])

同时, Ed 由于觉得自己的密码不够安全,因此需要重新设置其密码:

>>> ed_user.password = 'f8s7ccs'

Session 会关注到这一切。例如,他知道Ed Jones 已经被改变了:

>>> session.dirty
IdentitySet([<User('ed','Ed Jones','f8s7ccs')>])

而且此时还有三个新的 User 对象未处理:

>>> session.new 
IdentitySet([<User('wendy','Wendy Williams','foobar')>,
<User('mary','Mary Contrary','xxg527')>,
<User('fred','Fred Flinstone','blah')>])

我们可以告知 Session 我们现在需要将这些改变写入数据库,并且提交这些事务,事务将会贯穿我们的始终。我们通过 commit() 命令来完成:

>>> session.commit()

UPDATE users SET password=? WHERE users.id = ?
('f8s7ccs', 1)
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('wendy', 'Wendy Williams', 'foobar')
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('mary', 'Mary Contrary', 'xxg527')
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('fred', 'Fred Flinstone', 'blah')
COMMIT

commit() 负责将那些改变保存到数据库,并提交这些事务。此时由 session 引用的连接资源会被归还给连接池。该 session 后续的操作将会发生在另一个新的事务中,该事务会在需要时重新申请新的连接资源。

如果我们此时查看 Ed 的 id 属性,他现在将会拥有一个值,而之前这个值为 None:

>>> ed_user.id

BEGIN
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
FROM users
WHERE users.id = ?
(1,)

1

当 Session 将新的数据插入到数据库之后,此本实例中,所有新生成的标识和数据库生成的默认值均可以使用,不管是立即访问到还是通过载入访问的方式。在本实例中,由于这是一个commit() 后的操作,整个数据将被重新载入。SQLAlchemy 默认情况下在一个新的事务第一次访问数据的时候会重新刷新数据,以保证数据的最新状态被访问到。重载数据的配置方式将在后续的 Sessions 章节中详细讲解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值