5

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

VACUUM FULL ANALYZE table

更新

错误是:“UnboundExecutionError:找不到在 SQL 表达式或此会话上配置的绑定”。与之前发出的 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 - 如何从事务块外的代码运行 VACUUM?. 这并不理想,但它有效。

4

5 回答 5

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 - 如何从事务块外的代码运行 VACUUM? 因为在这一切之下,sqlalchemy 使用 psycopg 建立与 postgres 的连接。Connection.connection 是 psycopg 连接的代理。一旦我意识到这一点,这个问题又回到了我的脑海,我决定再试一次。

希望这可以帮助某人。

于 2010-01-19T19:39:42.020 回答
2

您需要将会话绑定到引擎

session.bind = metadata.bind
session.execute('YOUR SQL STATEMENT')
于 2010-01-11T16:02:56.240 回答
1

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

InternalError表示您正在尝试在显式(使用 BEGIN 语句)启动的事务中执行此语句。你有没有在没有打电话的情况下发表过一些声明commit()?如果是这样,只需在执行 VACUUM 之前调用commit()或方法来关闭事务。rollback()另请注意,有几个参数可以sessionmaker()告诉 SQLAlchemy 何时启动事务。

于 2009-12-10T11:27:24.990 回答
0

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

session.execute("VACUUM FULL ANALYZE table")
于 2009-12-09T18:53:08.860 回答
0

(取决于 Postgres 版本)您很可能不想运行“VACUUM FULL”。

于 2009-12-10T10:42:42.083 回答