2009-12-09 21 views
5

私は、postgresデータベースに接続するプロジェクトでElixirを使用しています。私は接続されているデータベースで次のクエリを実行したいが、私はElixirとSQLAlchemyを使い慣れていないので、どのように行うのか分からない。誰でも知っている?エリクシールでSQLクエリを実行

VACUUM FULL ANALYZE table

更新

エラーがある: "UnboundExecutionError:SQL式またはこのセッションで構成されたバインドが見つかりませんでした"。 session.close()と同じ結果が以前に発行されました。私はmetadata.bind.execute()を実行しようとしましたが、それは簡単な選択のために働いていました。しかし、VACUUMについては、 "InternalError:(InternalError)VACUUMはトランザクションブロック内で実行できません"というように、今私はそれをオフにする方法を理解しようとしています。

アップデート2

私は、クエリを実行するために取得することができますが、私はまだ同じエラーを取得しています - 私は新しいセッションを作成し、前の1を閉じた場合でも。

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' 

はこれを解決するには、これはそれをすべての下、SQLAlchemyのはpostgresのへの接続を行うためにpsycopgを使用しているため、ここでPostgreSQL - how to run VACUUM from code outside transaction block? を示唆したものと類似しているような単純な

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) 

ようでした。 Connection.connectionはpsycopg接続のプロキシです。私はこれを理解した後、この問題が心に戻ってきたので、私はもう一度それを打つことにしました。

これは誰かを助けてくれることを願っています。

0

あなたはSQLAlchemyのセッションへのアクセス権を持っている場合、あなたはそのexecuteメソッドを経由して、任意のSQL文を実行することができます:あなたの最も可能性の高いdo not want "FULL VACUUM" を実行するために(Postgresのバージョンに応じて)

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

私はそれを試みましたが、私はUnboundExecutionErrorを得ました。 sessionはsqlalchemy.orm.scoping.ScopedSessionのインスタンスです。私が他のクエリのsession.commit()を呼び出すと、それが動作します。それがコミットの前か後かどうかは重要ですか? – mozillalives

+0

ステートメントを実行する前にsession.close()を実行しようとすることができます。また、エラーがうまくトレースバックと一緒に来た、それは何と言う? –

+0

"UnboundExecutionError:SQL式またはこのセッションで構成されたバインドを見つけることができませんでした"。 session.close()と同じ結果が以前に発行されました。私はmetadata.bind.execute()を実行しようとしましたが、それは簡単な選択のために働いていました。しかし、VACUUMについては、 "InternalError:(InternalError)VACUUMはトランザクションブロック内で実行できません"というように、今私はそれをオフにする方法を理解しようとしています。 – mozillalives

0

1

UnboundExecutionErrorは、セッションがエンジンにバインドされておらず、​​に渡されたクエリからエンジンを検出する方法がないと言います。 engine.execute()を直接使用するか、またはmapperパラメータ(クエリで使用されるテーブルに対応するマッパーまたはマップモデルのいずれか)をsession.execute()に渡して、SQLAlchemyが適切なエンジンを検出できるようにすることができます。

InternalErrorは、明示的に(BEGIN文を使用して)開始されたトランザクション内でこの文を実行しようとしていると言います。あなたはcommit()と呼ぶことなく、その前にいくつかの声明を出しましたか?その場合は、VACUUMを実行する前にcommit()またはrollback()メソッドを呼び出してトランザクションを終了してください。また、トランザクションが開始されるべきときにSQLAlchemyに指示するいくつかのパラメータがsessionmaker()にあることにも注意してください。

+0

ああ、ありがとう。私はそれを試してみましたが(更新2参照)、まだどこかでトランザクションを開始しているようです。 echo_pool = Trueの場合、出力は新しい接続が行われていることを示しています。 – mozillalives

2

あなたがエンジン

session.bind = metadata.bind 
session.execute('YOUR SQL STATEMENT') 
関連する問題