2009-12-09 13 views
5

के साथ एसक्यूएल क्वेरी निष्पादित करें मैं एक प्रोजेक्ट में एलिक्सीर का उपयोग कर रहा हूं जो पोस्टग्रेज़ डेटाबेस से जुड़ता है। मैं उस डेटाबेस पर निम्न क्वेरी को चलाने के लिए चाहता हूं जिसे मैं कनेक्ट कर रहा हूं, लेकिन मुझे यकीन नहीं है कि यह कैसे करना है क्योंकि मैं इलीक्सिर और स्क्लाक्लेमी के लिए नया हूं। किसी को पता है कैसे?एलिक्सीर

VACUUM FULL ANALYZE table

अद्यतन

त्रुटि है: "UnboundExecutionError: एक बाँध एसक्यूएल अभिव्यक्ति या इस सत्र पर कॉन्फ़िगर पता नहीं लग सका"। और उसी परिणाम के साथ session.close() जारी किया गया। मैंने metadata.bind.execute() करने का प्रयास किया और यह एक साधारण चयन के लिए काम किया। लेकिन वाक्यूम के लिए यह कहा गया - "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

Dammit को सत्र बाध्य करने के लिए की जरूरत है। मुझे पता था कि जवाब मेरी नाक के नीचे सही होगा। मान लीजिए कि आपने अपना कनेक्शन सेटअप किया है जैसा मैंने किया था।

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 postgres के लिए कनेक्शन बनाने के लिए psycopg का उपयोग करता है के समान है था। कनेक्शन.कनेक्शन psycopg कनेक्शन के लिए एक प्रॉक्सी है। एक बार मुझे यह एहसास हुआ, यह समस्या वापस आ गई और मैंने उस पर एक और झटका लेने का फैसला किया।

उम्मीद है कि यह किसी की सहायता करता है।

0

आप SQLAlchemy सत्र के लिए उपयोग किया है, तो आप अपने execute विधि के माध्यम से मनमाने ढंग से SQL कथन निष्पादित कर सकते हैं:

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

मैंने कोशिश की, लेकिन मुझे एक UnboundExecutionError मिला। सत्र sqlalchemy.orm.scoping.ScopedSession का एक उदाहरण है और जब मैं session.commit() को अपने अन्य प्रश्नों के लिए कॉल करता हूं, जो काम करता है। क्या इससे कोई फर्क पड़ता है कि यह प्रतिबद्धता से पहले या उसके बाद है? – mozillalives

+0

आप कथन निष्पादित करने से पहले session.close() करने का प्रयास कर सकते हैं। इसके अलावा, त्रुटि उम्मीद है कि ट्रेसबैक के साथ आया, यह क्या कहता है? –

+0

"UnboundExecutionError: SQL अभिव्यक्ति या इस सत्र पर कॉन्फ़िगर किए गए बाइंड का पता नहीं लगा सका"। और उसी परिणाम के साथ session.close() जारी किया गया। मैंने metadata.bind.execute() करने का प्रयास किया और यह एक साधारण चयन के लिए काम किया। लेकिन वाक्यूम के लिए यह कहा गया - "InternalError: (InternalError) VACUUM लेनदेन ब्लॉक के अंदर नहीं चलाया जा सकता है", इसलिए अब मैं इसे बंद करने का तरीका समझने की कोशिश कर रहा हूं। – mozillalives

0

(Postgres संस्करण के आधार पर) आप सबसे अधिक संभावना do not want "वैक्यूम पूर्ण" चलाने के लिए।

1

UnboundExecutionError कहता है कि आपका सत्र किसी इंजन से बंधे नहीं है और execute() पर क्वेरी से इंजन खोजने का कोई तरीका नहीं है। आप या तो engine.execute() सीधे का उपयोग करें या SQLAlchemy उचित इंजन को खोजने में मदद करने के लिए session.execute() करने के लिए अतिरिक्त mapper पैरामीटर (या तो नक्शाकार या मैप किए गए मॉडल क्वेरी में उपयोग तालिका के अनुरूप) पारित कर सकते हैं।

InternalError का कहना है कि आप (बयान शुरू के साथ) के अंदर स्पष्ट रूप से इस बयान पर अमल करने की कोशिश कर रहे लेन-देन शुरू कर दिया। क्या आपने commit() पर कॉल किए बिना कुछ बयान जारी किए हैं? यदि हां, तो सिर्फ वैक्यूम करने से पहले लेन-देन बंद करने के लिए commit() या rollback() विधि कॉल। यह भी ध्यान दें कि sessionmaker() पर कई पैरामीटर हैं जो लेनदेन शुरू होने पर SQLAlchemy बताते हैं।

+0

आह, धन्यवाद। मैंने कोशिश की है (अपडेट 2 देखें) लेकिन यह अभी भी एक लेनदेन शुरू कर रहा है। मैंने सोचा कि शायद यह पुराने कनेक्शन का पुन: उपयोग कर रहा था, लेकिन echo_pool = True के साथ आउटपुट इंगित करता है कि एक नया कनेक्शन बनाया जा रहा है। – mozillalives

2

आप एक इंजन

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