Я пытаюсь установить соединение с несколькими базами данных.Сейчас я могу создать соединение с одним движком для нескольких баз данных.Это работает для моей основной базы данных (Shared database), определенной в mainschema.py (псевдоним dbm):
mymetadata = MetaData()
Base = declarative_base(metadata=mymetadata)
class newbase(DeferredReflection, Base):
__abstract__ = True
table_args = {
'mysql_engine': dict_constants['sql_mainDB_engine'],
'mysql_charset': dict_constants['sql_mainDB_collation'],
'schema' : 'smv',
}
class Company(newbase):
__tablename__ = 'companies'
__table_args__ = table_args
id = Column(INTEGER(unsigned=True), primary_key=True)
company = Column(String(255))
db = Column(String(255))
enabled = Column(BOOLEAN, nullable=False)
Тогда для каждого клиента у меня будет определенная база данных, определенная в dbschema.py (псевдоним dbc)
mymetadata = MetaData()
Base = declarative_base()
table_args = {
'mysql_engine': dict_constants['sql_mainDB_engine']
}
# __abstract__ causes declarative to skip the production of a table or mapper for the class entirely
class newbase(DeferredReflection, Base):
__abstract__ = True
#Creating Base Classes
class ObjectGroup(newbase):
__tablename__ = 'objectgroups'
__table_args__ = table_args
id = Column(INTEGER(unsigned=True), primary_key=True, autoincrement=True)
name = Column(String(30), unique=True, nullable=False)
parentobjectgroup_id = Column(INTEGER(unsigned=True), ForeignKey(id,onupdate="CASCADE", ondelete="RESTRICT"), nullable=False)
created_at = Column(DATETIME, nullable=False)
updated_at = Column(DATETIME, nullable=False)
enabled = Column(BOOLEAN, nullable=False)
После этого я создаю движок:
self.clientconnection = '%s://%s:%s@%s:%s/%s?charset=%s&use_unicode=0' % (self.dict_constants['sql_clientDB_driver'],
self.dict_constants['sql_clientDB_user'], self.dict_constants['sql_clientDB_passwd'],
host, port, db, self.dict_constants['sql_mainDB_collation'])
self.engine = create_engine(self.clientconnection, echo=False, pool_size=1, pool_timeout=30)
self.base = dbc.newbase
#opening several threads on the same time produces error in prepare, only one at a time
with sema_clientengine:
try:
self.base.prepare(self.engine)
пример запроса:
position_table = dbc.Position.__table__
position = alias(position_table, name='position', flat=True)
filter = and_(position.c.object_id == objectid, position.c.validpos == 1)
query = select([position]).where(filter).order_by(position.c.moment_id.desc()).limit(1)
Вот как я прочитал:
with sema_reads:
debug_starttime = time()
try:
self.engine.dispose()
with self.engine.connect() as connection:
proxyobject = connection.execute(query)
Хорошо, так что в основном у меня в одном экземпляре одна основная база данных, называемая smv, и для каждого клиента независимая БД.
Поэтому, когда я создаю движок и запускаю соединение в зависимости от класса, оно будетперейти к определенной схеме.Это прекрасно работает, я даже могу объединять базы данных.Теперь мне нужно поместить основную базу данных «smv» в другой экземпляр БД, чтобы я мог масштабироваться, и вот, когда все перестает работать, потому что общий движок подключается только к экземпляру клиентов, и теперь схема smv не существует.
Есть идеи?
Добавлено 2019-02-05:
Хорошо, после некоторого тестирования я могу заставить его работать с сессиями, обратите внимание, что таблица Company не просто находится в другой базе данных, чемОбъекты, находящиеся в другом экземпляре базы данных, с разными IP и портом:
config_1 = {
"sqlalchemy.url": "%s://%s:%s@%s:%s/%s" % (dict_constants['sql_mainDB_driver'], dict_constants['sql_mainDB_user'],
dict_constants['sql_mainDB_passwd'], dict_constants['sql_mainDB_host'],
dict_constants['sql_mainDB_port'], dict_constants['sql_mainDB_name']),
"sqlalchemy.echo": False,
}
config_2 = {
"sqlalchemy.url": "%s://%s:%s@%s:3307/clientdb" % (dict_constants['sql_mainDB_driver'], dict_constants['sql_mainDB_user'],
dict_constants['sql_mainDB_passwd'], dict_constants['sql_mainDB_host']),
"sqlalchemy.echo": False,
}
engine_1 = engine_from_config(config_1)
engine_2 = engine_from_config(config_2)
Base = declarative_base()
Base2 = declarative_base()
class Company(Base):
__tablename__ = 'companies'
id = Column(INTEGER(unsigned=True), primary_key=True)
company = Column(String(255))
db = Column(String(255))
enabled = Column(BOOLEAN, nullable=False)
class Object(Base2):
__tablename__ = 'objects'
id = Column(INTEGER(unsigned=True), primary_key=True)
name = Column(String(30), unique=True, nullable=False)
objectgroup_id = Column(INTEGER(unsigned=True), nullable=False)
objectaction_id = Column(SMALLINT(unsigned=True), nullable=False)
created_at = Column(DATETIME, nullable=False)
updated_at = Column(DATETIME, nullable=False)
enabled = Column(BOOLEAN, nullable=False)
#session.configure(bind={Company:engine_1})
binds = {Base:engine_1, Base2:engine_2}
session = sessionmaker(binds=binds)
session = session()
print session.query(Company).all()
print session.query(Object).all()
Так что это работает, но мне нужно выполнять более сложные запросы, и для меня это лучше, но это работает только тогда, когда яуказать двигатель.Любой способ, которым сессия обнаруживает это автоматически в зависимости от класса таблицы?Также возможно ли выполнить объединение с таблицами из другого экземпляра базы данных?
company = alias(Company.__table__, name='company', flat=True)
query = select([Company]).order_by(company.c.company)
proxyobject = session.execute(query, bind=engine_1)
rows = proxyobject.fetchall()
print rows