使用Elixir执行sql查询

时间:2009-12-09 18:36:02

标签: python postgresql sqlalchemy python-elixir

我在连接到postgres数据库的项目中使用Elixir。我想在我连接的数据库上运行以下查询,但我不知道该怎么做,因为我对Elixir和SQLAlchemy很新。谁知道怎么做?

VACUUM FULL ANALYZE table

更新

错误是:“UnboundExecutionError:找不到在SQL表达式或此Session上配置的绑定”。与之前发布的session.close()相同的结果。我确实尝试过metadata.bind.execute(),这对于一个简单的选择很有用。但对于VACUUM,它说 - “InternalError:(InternalError)VACUUM无法在事务块内运行”,所以现在我想弄清楚如何关闭它。

更新2

我可以让查询执行,但我仍然会收到同样的错误 - 即使我创建了一个新会话并关闭了前一个会话。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# ... insert stuff
old_session.commit()
old_session.close()

new_sess = sessionmaker(autocommit=True)
new_sess.configure(bind=create_engine('postgres://user:pw@host/db', echo=True))
sess = new_sess()
sess.execute('VACUUM FULL ANALYZE table')
sess.close()

我得到的输出是

2009-12-10 10:00:16,769 INFO sqlalchemy.engine.base.Engine.0x...05ac VACUUM FULL ANALYZE table
2009-12-10 10:00:16,770 INFO sqlalchemy.engine.base.Engine.0x...05ac {}
2009-12-10 10:00:16,770 INFO sqlalchemy.engine.base.Engine.0x...05ac ROLLBACK
finishing failed run, (InternalError) VACUUM cannot run inside a transaction block
 'VACUUM FULL ANALYZE table' {}

更新3

感谢所有回复的人。 我无法找到我想要的解决方案,但我想我会选择这里描述的那个PostgreSQL - how to run VACUUM from code outside transaction block?。它并不理想,但它确实有效。

5 个答案:

答案 0 :(得分:10)

该死。我知道答案就在我的鼻子底下。假设您像我一样设置连接。

metadata.bind = 'postgres://user:pw@host/db'

解决方法就像

一样简单
conn = metadata.bind.engine.connect()

old_lvl = conn.connection.isolation_level
conn.connection.set_isolation_level(0)
conn.execute('vacuum analyze table')
conn.connection.set_isolation_level(old_lvl)

这类似于此处PostgreSQL - how to run VACUUM from code outside transaction block?的建议 因为在它之下,sqlalchemy使用psycopg建立与postgres的连接。 Connection.connection是psycopg连接的代理。一旦我意识到这一点,这个问题又浮现在脑海中,我决定再次采取行动。

希望这有助于某人。

答案 1 :(得分:2)

您需要将会话绑定到引擎

session.bind = metadata.bind
session.execute('YOUR SQL STATEMENT')

答案 2 :(得分:1)

UnboundExecutionError表示您的会话未绑定到引擎,并且无法从传递给execute()的查询中发现引擎。您可以直接使用engine.execute()或将其他mapper参数(映射器或映射模型对应于查询中使用的表)传递给session.execute(),以帮助SQLAlchemy发现正确的引擎。

InternalError表示您正在尝试在显式内部(使用BEGIN语句)启动事务中执行此语句。您是否在没有致电commit()之前发表了一些声明?如果是这样,请在执行VACUUM之前调用commit()rollback()方法关闭事务。另请注意,sessionmaker()有几个参数可以告诉SQLAlchemy何时应该启动事务。

答案 3 :(得分:0)

如果您有权访问SQLAlchemy会话,则可以通过execute方法执行任意SQL语句:

session.execute("VACUUM FULL ANALYZE table")

答案 4 :(得分:0)

(取决于Postgres版本)您最有可能do not want运行“VACUUM FULL”。