sqlalchemy: создать две базы данных в одном файле - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь создать две отдельные базы данных в одном файле, используя SQLAlchemy.Вот код, который у меня есть:

from sqlalchemy import create_engine, Column, String, Integer, inspect
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Table1(Base):
    __tablename__ = 'table_1'
    id = Column(Integer, primary_key=True)
    name = Column(String)

class Table2(Base):
    __tablename__ = 'table_2'
    id = Column(Integer, primary_key=True)
    name = Column(String)


engine1 = create_engine('sqlite:///db1.db')
engine2 = create_engine('sqlite:///db2.db')
Base.metadata.drop_all(bind=engine1)
Base.metadata.drop_all(bind=engine2)
Base.metadata.create_all(bind=engine1)
Base.metadata.create_all(bind=engine2)

print(inspect(engine1).get_table_names())
# ['table_1', 'table_2']
print(inspect(engine2).get_table_names())
# ['table_1', 'table_2']

Я хочу создать только Table1 в db1 и только Table2 в db2;Тем не менее, я получаю обе таблицы в обеих базах данных.

Есть ли способ решить эту проблему или мне нужно создавать базы данных в двух отдельных файлах.

1 Ответ

0 голосов
/ 22 ноября 2018

Ваша проблема не вызвана попыткой создать две базы данных в одном модуле.Скорее, вы вызываете create_all() для того же объекта метаданных, который сопоставил обе таблицы.Например,

print(Base.metadata.tables)

результат:

dict_keys(['table_1', 'table_2'])

Из документов о MetaData.create_all():

Этот метод будет выдавать запросы, которыесначала проверяется наличие каждой отдельной таблицы, и, если она не найдена, выдаются операторы CREATE ...

Ключевым моментом является проверка наличия каждой таблицы.Так вот:

Base.metadata.create_all(bind=engine1)
Base.metadata.create_all(bind=engine2)

... сначала он проверяет обе таблицы в БД, на которые ссылается engine1, не находит их и создает их.Затем он проверяет обе таблицы в БД, на которые ссылается engine2, не находит их и создает их.

Есть несколько вариантов.

Имеют разные базовые объекты (т.е.отдельный экземпляр MetaData) для каждой базы данных:

Base1 = declarative_base()
Base2 = declarative_base()


class Table1(Base1):
    __tablename__ = 'table_1'
    id = Column(Integer, primary_key=True)
    name = Column(String)

class Table2(Base2):
    __tablename__ = 'table_2'
    id = Column(Integer, primary_key=True)
    name = Column(String)

engine1 = create_engine('sqlite:///db1.db')
engine2 = create_engine('sqlite:///db2.db')
Base1.metadata.drop_all(bind=engine1)
Base2.metadata.drop_all(bind=engine2)
Base1.metadata.create_all(bind=engine1)
Base2.metadata.create_all(bind=engine2)

print(inspect(engine1).get_table_names())
# ['table_1']
print(inspect(engine2).get_table_names())
# ['table_2']

Или выборочное создание таблиц при привязке к нужному механизму:

Base = declarative_base()

class Table1(Base):
    __tablename__ = 'table_1'
    id = Column(Integer, primary_key=True)
    name = Column(String)

class Table2(Base):
    __tablename__ = 'table_2'
    id = Column(Integer, primary_key=True)
    name = Column(String)


engine1 = create_engine('sqlite:///db1.db')
engine2 = create_engine('sqlite:///db2.db')
Base.metadata.drop_all(bind=engine1)
Base.metadata.drop_all(bind=engine2)
Base.metadata.tables['table_1'].create(bind=engine1)
Base.metadata.tables['table_2'].create(bind=engine2)

print(inspect(engine1).get_table_names())
# ['table_1']
print(inspect(engine2).get_table_names())
# ['table_2']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...