2009-12-09 2 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?과 함께 갈 것이라고 생각합니다. 이상적은 아니지만 작동합니다. 당신은 SQLAlchemy의 세션에 액세스 할 수있는 경우

답변

10

젠장에 세션을 결합해야합니다. 나는 대답이 내 코 바로 아래에 있음을 알았다. 내가했던 것처럼 당신이 당신의 연결을 설정한다고 가정합니다.

metadata.bind = 'postgres://user:[email protected]/db' 

이에 대한 해결책은이 모든 아래, SQLAlchemy의이 포스트 그레스에 연결을 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

, 당신은 execute 방법을 통해 임의의 SQL 문을 실행할 수 있습니다

(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

가능성이 가장 높은 do not want "FULL VACUUM"를 실행합니다.

1

UnboundExecutionError은 세션이 엔진에 연결되어 있지 않으며 execute()에 전달 된 쿼리에서 엔진을 찾을 방법이 없다고 말합니다. engine.execute()을 직접 사용하거나 mapper 매개 변수 (쿼리에 사용 된 테이블에 해당하는 매퍼 또는 매핑 된 모델)를 session.execute()으로 전달하여 SQLAlchemy가 적절한 엔진을 찾도록 할 수 있습니다.

InternalError은 명시 적으로 (BEGIN 문을 사용하여) 트랜잭션을 시작한 상태에서이 문을 실행하려고한다고합니다. commit() 번으로 전화하지 않고 그 전에 몇 가지 진술을 했습니까? 그렇다면 commit() 또는 rollback() 메서드를 호출하여 VACUUM을 수행하기 전에 트랜잭션을 닫으십시오. 또한 트랜잭션이 시작되어야 할 때 SQLAlchemy에 알려주는 sessionmaker()에 대한 몇 가지 매개 변수가 있습니다.

+0

아, 고마워. 나는 그것을 시도했다. (업데이트 2를 보아라.) 그러나 그것은 어딘가에서 트랜잭션을 시작하는 것처럼 보인다. echo_pool = True로 설정하면 새로운 연결이 생성되고 있음을 알 수 있습니다. – mozillalives

2

당신은 엔진

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