2009-12-09 129 views
5

我在连接到postgres数据库的项目中使用Elixir。我想在我连接的数据库上运行以下查询,但我不确定如何做,因为我对Elixir和SQLAlchemy相当陌生。任何人都知道吗?用Elixir执行sql查询

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:[email protected]/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?。这不是理想的,但它的工作原理。

回答

10

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

metadata.bind = 'postgres://user:[email protected]/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连接的代理。一旦我意识到这一点,这个问题就回到了脑海,我决定再次尝试。

希望这可以帮助别人。

0

如果你有机会获得SQLAlchemy的会议上,你可以通过它的execute方法执行任意SQL语句:

session.execute("VACUUM FULL ANALYZE table") 
+0

我试过了,但我得到了一个UnboundExecutionError。 session是sqlalchemy.orm.scoping.ScopedSession的一个实例,当我为其他查询调用session.commit()时,它就可以工作。如果它在提交之前或之后有关系吗? – mozillalives 2009-12-09 19:02:03

+0

您可以在执行语句之前尝试执行session.close()。此外,错误希望带有追溯,这是什么意思? – 2009-12-09 19:45:44

+0

“UnboundExecutionError:无法找到在SQL表达式或此会话上配置的绑定”。和之前发布的session.close()相同的结果。我没有尝试做metadata.bind.execute(),并为一个简单的选择工作。但是对于VACUUM,它说 - “InternalError:(InternalError)VACUUM无法在事务块内部运行”,所以现在我试图找出如何关闭它。 – mozillalives 2009-12-09 20:35:21

0

(视Postgres的版本),你最有可能do not want运行“真空FULL”。

1

UnboundExecutionError说,您的会话没有绑定到发动机没有办法发现从查询传递给​​引擎。您可以直接使用engine.execute()或将其他mapper参数(映射器或与查询中使用的表对应的映射模型)传递给session.execute()以帮助SQLAlchemy发现正确的引擎。

InternalError表示您试图在显式执行此语句(使用BEGIN语句)启动事务。你是否在没有致电commit()之前发表过一些声明?如果是这样,只需拨打commit()rollback()方法在执行VACUUM之前关闭事务。另请注意,sessionmaker()有几个参数告诉SQLAlchemy应在何时启动事务。

+0

啊,谢谢。我确实尝试过(见更新2),但它似乎仍然在某处开始交易。我想也许它只是重复使用旧的连接,但是echo_pool = True输出表明正在建立一个新的连接。 – mozillalives 2009-12-10 15:25:36

2

你需要的话绑定到发动机

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