首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用SQLAlchemy对象模型高效地更新数据库

使用SQLAlchemy对象模型高效地更新数据库
EN

Stack Overflow用户
提问于 2008-11-07 00:24:05
回答 6查看 204.8K关注 0票数 140

我正在启动一个新的应用程序,并考虑使用对象关系映射--特别是SQLAlchemy。

假设我的数据库中有一列'foo‘,我想要递增它。在简单的sqlite中,这很简单:

代码语言:javascript
复制
db = sqlite3.connect('mydata.sqlitedb')
cur = db.cursor()
cur.execute('update table stuff set foo = foo + 1')

我想出了SQL构建器的等价物:

代码语言:javascript
复制
engine = sqlalchemy.create_engine('sqlite:///mydata.sqlitedb')
md = sqlalchemy.MetaData(engine)
table = sqlalchemy.Table('stuff', md, autoload=True)
upd = table.update(values={table.c.foo:table.c.foo+1})
engine.execute(upd)

这稍微慢了一点,但里面的内容不多。

以下是我对SQLAlchemy对象关系管理方法的最佳猜测:

代码语言:javascript
复制
# snip definition of Stuff class made using declarative_base
# snip creation of session object
for c in session.query(Stuff):
    c.foo = c.foo + 1
session.flush()
session.commit()

这样做是正确的,但它所需的时间不到其他两种方法的50倍。我认为这是因为它必须将所有数据放入内存中,然后才能使用它。

有没有办法使用SQLAlchemy的ORM生成高效的SQL?或者使用任何其他的python ORM?或者,我应该继续手工编写SQL吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2008-11-10 17:40:43

SQLAlchemy的ORM旨在与SQL层一起使用,而不是隐藏它。但在同一事务中使用ORM和纯SQL时,您必须牢记一两件事。基本上,从一方面来说,ORM数据修改仅在您从会话中刷新更改时才会影响数据库。另一方面,SQL数据操作语句不会影响会话中的对象。

所以如果你说

代码语言:javascript
复制
for c in session.query(Stuff).all():
    c.foo = c.foo+1
session.commit()

它将照它说的做,从数据库中获取所有对象,修改所有对象,然后在刷新数据库更改时,逐个更新行。

相反,您应该这样做:

代码语言:javascript
复制
session.execute(update(stuff_table, values={stuff_table.c.foo: stuff_table.c.foo + 1}))
session.commit()

正如您所期望的那样,这将作为一个查询执行,并且因为至少默认会话配置在提交时会使会话中的所有数据过期,所以您不会有任何陈旧数据问题。

在即将发布的0.5系列中,您也可以使用此方法进行更新:

代码语言:javascript
复制
session.query(Stuff).update({Stuff.foo: Stuff.foo + 1})
session.commit()

这基本上会运行与前面代码片段相同的SQL语句,但也会选择更改过的行,并使会话中的所有陈旧数据失效。如果您知道在更新之后没有使用任何会话数据,那么还可以将synchronize_session=False添加到update语句中,并去掉那个select语句。

票数 206
EN

Stack Overflow用户

发布于 2010-12-28 00:28:03

代码语言:javascript
复制
session.query(Clients).filter(Clients.id == client_id_list).update({'status': status})
session.commit()

试试这个=)

票数 107
EN

Stack Overflow用户

发布于 2015-11-11 03:53:27

有多种使用sqlalchemy进行更新的方法

代码语言:javascript
复制
1) for c in session.query(Stuff).all():
       c.foo += 1
   session.commit()

2) session.query(Stuff).update({"foo": Stuff.foo + 1})
   session.commit()

3) conn = engine.connect()
   table = Stuff.__table__
   stmt = table.update().values({'foo': Stuff.foo + 'a'})
   conn.execute(stmt)
   conn.commit()
票数 37
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/270879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档