我在连接到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?。它并不理想,但它确实有效。
答案 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”。