2015-03-30 7 views
7

मुझे दूरस्थ रूप से MySQL तक पहुंचने में कठिनाई हो रही है। मैं एसएसएच सुरंग का उपयोग करता हूं और पाइथन + SQLALchemy का उपयोग कर डेटाबेस MySQL को कनेक्ट करना चाहता हूं।Python + SQLAlchemy दूरस्थ रूप से MySQL डेटाबेस को कैसे कनेक्ट करें?

जब मैं अपने कंसोल में MySQL-client का उपयोग करता हूं और "ptotocol=TCP" निर्दिष्ट करता हूं, तो सब कुछ ठीक है! मैं आदेश का उपयोग करें:

mysql -h localhost —protocol=TCP -u USER -p 

मैं SSH-सुरंग के माध्यम से दूरदराज के डेटाबेस के लिए पहुँच जाते हैं।

हालांकि, जब मैं पाइथन + स्क्लेक्की का उपयोग कर डेटाबेस से कनेक्ट करना चाहता हूं तो मुझे —protocol=TCP जैसे विकल्प नहीं मिल सकते हैं अन्यथा, मैंने केवल स्थानीय MySQL डेटाबेस से कनेक्ट किया है। कृपया मुझे बताएं, क्या एसक्यूएलकेमी का उपयोग करके ऐसा करने का कोई तरीका है।

+0

एक एसएसएच सुरंग स्थापित करें, फिर स्थानीय मशीन पर सुरंग बंदरगाह पर अपने स्थानीय mysql को इंगित करें। MySQL को यह नहीं पता होगा कि यह सुरंग हो रहा है, और एसएसएच जहां भी जाना चाहिए उसे पुनर्निर्देशित करने का ख्याल रखेगा। –

+0

सुरंग X.X.X.X से पहले ही स्थापित हो चुकी है: 3306 -> लोकलहोस्ट: 3306 शायद मुझे सुरंग को किसी अन्य बंदरगाह पर सेट करने की आवश्यकता है, उदाहरण के लिए लोकलहोस्ट: 3307? – strevg

+0

@strevg चीजों को स्पष्ट करने के लिए: आपके पास MySQL सर्वर आपके स्थानीय होस्ट पर चल रहा है। और एक दूसरा MySQL सर्वर एक एसएसएच सुरंग के माध्यम से दूरस्थ रूप से पहुंचा। दोनों एक साथ चल रहे हैं? कौन सा सर्वर आपके स्थानीय होस्ट पर कौन सा बंदरगाह से बंधे हैं? –

उत्तर

12

इस मुद्दे पर क्लासिक जवाब या 127.0.0.1 उपयोग करने के लिए है मेजबान की आईपी या होस्ट नाम "विशेष नाम" localhost के बजायdocumentation से:

[...] स्थानीय होस्ट को यूनिक्स पर कनेक्शन

और बाद में डिफ़ॉल्ट

द्वारा एक यूनिक्स सॉकेट फ़ाइल का उपयोग किया जाता:

यूनिक्स पर, MySQL प्रोग्राम होस्ट नाम लोकलहोस्ट विशेष रूप से का इलाज करते हैं, जिस तरह से आप अन्य नेटवर्क की तुलना में अपेक्षा की अपेक्षा से भिन्न होते हैं- आधारित कार्यक्रम। स्थानीयहोस्ट से कनेक्शन के लिए, MySQL प्रोग्राम यूनिक्स सॉकेट फ़ाइल का उपयोग करके स्थानीय सर्वर से कनेक्ट करने का प्रयास करता है। यह तब भी होता है जब पोर्ट नंबर निर्दिष्ट करने के लिए एकपोर्ट या -पी विकल्प दिया जाता है। यह सुनिश्चित करने के लिए कि क्लाइंट स्थानीय सर्वर से एक टीसीपी/आईपी कनेक्शन बनाता है, 127.0.0.1 का होस्ट नाम मान निर्दिष्ट करने के लिए --host या -h का उपयोग करें, या स्थानीय सर्वर का आईपी पता या नाम निर्दिष्ट करें।


हालांकि, इस सरल चाल अपने मामले में काम करने के लिए प्रकट नहीं होता है, तो आप किसी भी तरह के बल TCP सॉकेट के उपयोग की है। जैसा कि आपने इसे स्वयं समझाया है, कमांड लाइन पर mysql का आविष्कार करते समय, आप --protocol tcp विकल्प का उपयोग करते हैं।

के रूप में समझाया here, SQLAlchemy से, आप प्रासंगिक विकल्प (यदि हो तो) अपने ड्राइवर को पारित कर सकते हैं या तो या के रूप में URL विकल्प connect_args कीवर्ड तर्क का उपयोग।

PyMySQL का उपयोग कर उदाहरण के लिए

, एक परीक्षण प्रणाली पर मुझे लगता है कि इस प्रयोजन के लिए सेट किया हुआ (MariaDB 10.0.12, SQLAlchemy 0.9.8 और 0.6.2 PyMySQL) मुझे मिल निम्न परिणाम:

>>> engine = create_engine(
     "mysql+pymysql://sylvain:[email protected]/db?host=localhost?port=3306") 
#             ^^^^^^^^^^^^^^^^^^^^^^^^^^ 
#        Force TCP socket. Notice the two uses of `?` 
#        Normally URL options should use `?` and `&` 
#        after that. But that doesn't work here (bug?) 
>>> conn = engine.connect() 
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall() 
[('localhost:54164',)] 

# Same result by using 127.0.0.1 instead of localhost: 
>>> engine = create_engine(
     "mysql+pymysql://sylvain:[email protected]/db?host=localhost?port=3306") 
>>> conn = engine.connect() 
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall() 
[('localhost:54164',)] 

# Alternatively, using connect_args: 
>>> engine = create_engine("mysql+pymysql://sylvain:[email protected]/db", 
         connect_args= dict(host='localhost', port=3306)) 
>>> conn = engine.connect() 
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall() 
[('localhost:54353',)] 

जैसा कि आपने देखा है, दोनों एक टीसीपी कनेक्शन का उपयोग करेंगे (मुझे पता है कि होस्टनाम के बाद पोर्ट नंबर की वजह से)।दूसरी ओर:

>>> engine = create_engine(
     "mysql+pymysql://sylvain:[email protected]/db?unix_socket=/path/to/mysql.sock") 
#             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
#        Specify the path to mysql.sock in 
#        the `unix_socket` option will force 
#        usage of a UNIX socket 

>>> conn = engine.connect() 
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall() 
[('localhost',)] 

# Same result by using 127.0.0.1 instead of localhost: 
>>> engine = create_engine(
     "mysql+pymysql://sylvain:[email protected]/db?unix_socket=/path/to/mysql.sock") 
>>> conn = engine.connect() 
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall() 
[('localhost',)] 

# Alternatively, using connect_args: 
>>> engine = create_engine("mysql+pymysql://sylvain:[email protected]/db", 
         connect_args= dict(unix_socket="/path/to/mysql.sock")) 
>>> conn = engine.connect() 
>>> conn.execute("SELECT host FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = CONNECTION_ID()").fetchall() 
[('localhost',)] 

होस्ट नाम के बाद कोई बंदरगाह: यह एक यूनिक्स सॉकेट है।

+1

अच्छा। यह मेरे लिए एक स्थानीय (गैर-रूट) mysql स्थापना के साथ काम करने के लिए भी काम करता था, जहां मेरे पास सेट करने के लिए आवश्यक एक गैर मानक 'पोर्ट' और 'unix_socket' था। –

+0

दुर्भाग्य से, MySQLdb अधिक सख्त हो गया प्रतीत होता है। अब आपको एक टाइप एरर मिलता है, बीक्यूज एसक्यूएलकेमी पोर्ट में एक स्ट्रिंग के रूप में गुजर रहा है और MySQLdb एक int की अपेक्षा करता है। :/ –

5

मेरे सेटअप में (मैं mysql-python का उपयोग कर रहा हूं) MySQL SQLAlchemy url कार्यों में स्थानीयहोस्ट के बजाय 127.0.0.1 का उपयोग कर रहा हूं। पूर्ण url मुझे लगता है कि परिदृश्य के लिए वास्तव में उपयोग कर रहा हूँ (स्थानीय बंदरगाह 3307 के साथ सुरंग) है:

mysql:/user:[email protected]:3307/ 

मैं SQLAlchemy 1.0.5 का उपयोग कर रहा है, लेकिन मैं उस बात नहीं है बहुत ज्यादा ...

लगता है
+2

दरअसल, 127.0.0.1 लोकहोस्ट, @ बीके 435 है, लेकिन यह 127.0.0.1 के बजाय लोकलहोस्ट के साथ काम नहीं करता है। ऐसा लगता है कि musql "localhost" से कैसे संबंधित है, टीसीपी सॉकेट के बजाय फाइल सिस्टम सॉकेट के माध्यम से कनेक्ट करने का आग्रह करता है। यही कारण है कि विकल्प में mysql के लिए विकल्प --protocol = tcp का उल्लेख किया गया है। लेकिन ऐसा लगता है कि 127.0.0.1 चाल करता है, और वर्तमान उत्तर से सरल है। – jgbarah

संबंधित मुद्दे