12

我有一个与 sqlalchemy 和 postgresql 相关的问题。

class Profile(Base):
  ...

  roles = relationship('Role', secondary=role_profiles,
                       backref='profiles', lazy='dynamic')

运行时(current_userProfile类的一个实例):

roles = current_user.roles.filter().all()

使用 sqlalchemy,我获得idle in transaction了在 postgresql 中读取配置文件的所有选择。

编辑:

通过回显查询,我看到每个选择都以:

BEGIN (implicit)

另一个编辑:

添加后

pool_size=20, max_overflow=0

似乎当空闲数量变大时create_engineidle in transaction-statements 正在回滚。对此有任何想法吗?这会是解决问题的坏方法吗?

我该如何管理这个,我将如何摆脱BEGINfor 选择?

4

2 回答 2

5

从 SQLAlchemy 0.8.2 开始,您可以BEGIN在调用时禁用隐式语句create_engine()

engine = create_engine(uri, isolation_level="AUTOCOMMIT")

这种变化有一些微妙的影响。首先,有没有悄悄隐藏在未终止事务中的语句将被悄悄忽略

session.execute("DELETE FROM department WHERE department_id=18")
sys.exit(0)

默认

LOG:  statement: BEGIN
LOG:  statement: show standard_conforming_strings
LOG:  statement: DELETE FROM department WHERE department_id=18
LOG:  unexpected EOF on client connection with an open transaction

自动提交

LOG:  statement: show standard_conforming_strings
LOG:  statement: DELETE FROM department WHERE department_id=18

其次,更新多个更新不再是自动的,而rollback()只是有条件地有效:

department = Department(u"HR")
session.add(department)
session.flush()
employee = Employee(department.department_id, u'Bob')
session.add(employee)
session.rollback()

默认

LOG:  statement: BEGIN
LOG:  statement: INSERT INTO department (name) VALUES ('HR') RETURNING department.department_id
LOG:  statement: ROLLBACK

自动提交

LOG:  statement: INSERT INTO department (name) VALUES ('HR') RETURNING department.department_id

在 Engine 对象上设置 SQLAlchemyisolation_level对许多应用程序都很有效。不幸的是,Session.begin()这并不总是意味着BEGIN TRANSACTION;

于 2015-10-12T20:54:46.567 回答
2

默认情况下,SQLA 总是在事务中运行(这里有一些信息)。在 Web 上下文中,大多数框架会在请求结束时为您处理提交此事务(例如pyramid_tm)。如果您没有使用框架,或者这是另一种类型的应用程序,您将希望在完成时或在适当的时候提交或回滚。

可以配置 SQLA 使其不会自动启动事务,但据我所知,这不是它的预期用途,因此您可能会比较幸运,不要试图与之抗争:)。

于 2014-03-07T04:35:44.143 回答