Как объединить таблицы из двух разных баз данных с помощью языка выражений sqlalchemy/ядра sqlalchemy?

Я использую MySQL. Однако мне удалось найти способы сделать это, используя sqlalchemy orm, но не используя язык выражений. Поэтому я специально ищу решения на основе языка ядра/выражения. Базы лежат на одном сервере

Вот как выглядит мое подключение:

connection = engine.connect().execution_options(
schema_translate_map = {current_database_schema: new_database_schema})
engine_1=create_engine("mysql+mysqldb://root:user@*******/DB_1")
engine_2=create_engine("mysql+mysqldb://root:user@*******/DB_2",pool_size=5)

metadata_1=MetaData(engine_1)
metadata_2=MetaData(engine_2)

metadata.reflect(bind=engine_1)
metadata.reflect(bind=engine_2)

table_1=metadata_1.tables['table_1']
table_2=metadata_2.tables['table_2']
query=select([table_1.c.name,table_2.c.name]).select_from(join(table_2,table_1.c.id==table_2.c.id,'left')

result=connection.execute(query).fetchall()

Однако, когда я пытаюсь соединить таблицы из разных баз данных, выдается ошибка, очевидно, потому что соединение принадлежит одной из баз данных. И я больше ничего не пробовал, потому что не смог найти способ решить эту проблему. Другой способ поставить вопрос (возможно) - «как подключиться к нескольким базам данных, используя одно соединение в ядре sqlalchemy».


person Indhuja Ravi    schedule 02.07.2018    source источник
comment
Это решение, похоже, не работает. Выдает ключевую ошибку при доступе к таблице с использованием метаданных.   -  person Indhuja Ravi    schedule 02.07.2018


Ответы (1)


Применяя решение из здесь только к Core, вы можете создать один Engine объект, который подключается к вашему серверу, но без использования по умолчанию той или иной базы данных:

engine = create_engine("mysql+mysqldb://root:user@*******/")

а затем с помощью одного экземпляра MetaData отразить содержимое каждой схемы:

metadata = MetaData(engine)
metadata.reflect(schema='DB_1')
metadata.reflect(schema='DB_2')

# Note: use the fully qualified names as keys
table_1 = metadata.tables['DB_1.table_1']
table_2 = metadata.tables['DB_2.table_2']

Вы также можете использовать одну из баз данных в качестве «по умолчанию» и передать ее в URL-адресе. В этом случае вы должны отражать таблицы из этой базы данных, как обычно, и передавать аргумент ключевого слова schema= только при отражении другой базы данных.

Используйте созданный движок для выполнения запроса:

query = select([table_1.c.name, table_2.c.name]).\
    select_from(outerjoin(table1, table_2, table_1.c.id == table_2.c.id))

with engine.begin() as connection:
    result = connection.execute(query).fetchall()
person Ilja Everilä    schedule 02.07.2018
comment
Привет. Очень новичок во всем этом. Могу я спросить, не пропустили ли вы какие-либо шаги между отражением метаданных и построением запроса? Почему вы не использовали Base = automap_base(metadata=metadata) и Base.prepare()? - person Jossy; 08.07.2020