MySQL में डेटाबेस स्कीमा का पर्याय हैं . उदाहरण के लिए Postgresql में आप डेटाबेस में कई स्कीमाओं के बीच क्वेरी कर सकते हैं, लेकिन डेटाबेस (सीधे) के बीच नहीं, आप MySQL में कई डेटाबेस के बीच क्वेरी कर सकते हैं क्योंकि दोनों के बीच कोई अंतर नहीं है।
इस आलोक में MySQL में आपकी बहु-डेटाबेस क्वेरी का एक संभावित समाधान यह हो सकता है कि एक इंजन, सत्र, और बेस आपके दोनों स्कीमाओं को संभाले और schema
कीवर्ड तर्क
आपकी टेबल पर, या दोनों स्कीमाओं को प्रतिबिंबित करना ताकि वे पूरी तरह से योग्य हों।
चूँकि मेरे पास आपका डेटा नहीं है, इसलिए मैंने sopython और sopython2 नामक एक परीक्षण सर्वर पर 2 स्कीमा (MySQL डेटाबेस) बनाए:
mysql> create database sopython;
Query OK, 1 row affected (0,00 sec)
mysql> create database sopython2;
Query OK, 1 row affected (0,00 sec)
और प्रत्येक में एक तालिका जोड़ी:
mysql> use sopython
Database changed
mysql> create table foo (foo_id integer not null auto_increment primary key, name text);
Query OK, 0 rows affected (0,05 sec)
mysql> insert into foo (name) values ('heh');
Query OK, 1 row affected (0,01 sec)
mysql> use sopython2
Database changed
mysql> create table bar (bar_id integer not null auto_increment primary key, foo_id integer, foreign key (foo_id) references `sopython`.`foo` (foo_id)) engine=InnoDB;
Query OK, 0 rows affected (0,07 sec)
mysql> insert into bar (foo_id) values (1);
Query OK, 1 row affected (0,01 sec)
पायथन में:
In [1]: from sqlalchemy import create_engine
In [2]: from sqlalchemy.orm import sessionmaker
In [3]: from sqlalchemy.ext.automap import automap_base
In [4]: Session = sessionmaker()
In [5]: Base = automap_base()
डिफ़ॉल्ट रूप से आप किस स्कीमा (डेटाबेस) का उपयोग करते हैं, यह निर्दिष्ट किए बिना इंजन बनाएं:
In [6]: engine = create_engine('mysql+pymysql://user:[email protected]:6603/')
In [7]: Base.prepare(engine, reflect=True, schema='sopython')
In [8]: Base.prepare(engine, reflect=True, schema='sopython2')
/home/user/SO/lib/python3.5/site-packages/sqlalchemy/ext/declarative/clsregistry.py:120: SAWarning: This declarative base already contains a class with the same class name and module name as sqlalchemy.ext.automap.foo, and will be replaced in the string-lookup table.
item.__name__
चेतावनी कुछ ऐसी है जिसे मैं पूरी तरह से समझ नहीं पा रहा हूं, और शायद 2 तालिकाओं के बीच विदेशी कुंजी संदर्भ का परिणाम है जो फू को फिर से प्रतिबिंबित करता है, लेकिन ऐसा लगता है कि यह परेशानी का कारण नहीं बनता है।
चेतावनी दूसरी कॉल का परिणाम है prepare()
पहली कॉल में परिलक्षित तालिकाओं के लिए कक्षाओं को फिर से बनाना और बदलना। इन सब से बचने का तरीका यह है कि पहले मेटाडेटा का उपयोग करके दोनों स्कीमाओं से तालिकाओं को प्रतिबिंबित करें, और फिर तैयार करें:
Base.metadata.reflect(engine, schema='sopython')
Base.metadata.reflect(engine, schema='sopython2')
Base.prepare()
इन सबके बाद आप फू और बार में शामिल होने के बारे में पूछ सकते हैं:
In [9]: Base.metadata.bind = engine
In [10]: session = Session()
In [11]: query = session.query(Base.classes.bar).\
...: join(Base.classes.foo).\
...: filter(Base.classes.foo.name == 'heh')
In [12]: print(query)
SELECT sopython2.bar.bar_id AS sopython2_bar_bar_id, sopython2.bar.foo_id AS sopython2_bar_foo_id
FROM sopython2.bar INNER JOIN sopython.foo ON sopython.foo.foo_id = sopython2.bar.foo_id
WHERE sopython.foo.name = %(name_1)s
In [13]: query.all()
Out[13]: [<sqlalchemy.ext.automap.bar at 0x7ff1ed7eee10>]
In [14]: _[0]
Out[14]: <sqlalchemy.ext.automap.bar at 0x7ff1ed7eee10>
In [15]: _.foo
Out[15]: <sqlalchemy.ext.automap.foo at 0x7ff1ed7f09b0>