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 - how to run VACUUM from code outside transaction block? . 理想的ではありませんが、機能します。

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()。SQLAlchemy が適切なエンジンを検出できるように、engine.execute()直接使用するか、追加のmapperパラメーター (クエリで使用されるテーブルに対応するマッパーまたはマップされたモデル) を渡すことができます。session.execute()

は、明示的に (BEGIN ステートメントを使用して) 開始されたトランザクション内でこのInternalErrorステートメントを実行しようとしていると言います。を呼び出すことなく、その前にいくつかのステートメントを発行しましたかcommit()? その場合は、 VACUUM を実行する前にトランザクションを閉じるために呼び出しcommit()またはメソッドを実行してください。また、トランザクションをいつ開始する必要があるかを SQLAlchemy に伝えるrollback()パラメータがいくつかあることに注意してください。sessionmaker()

于 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 に答える