sqlalchemy:在同一文件中创建两个数据库

时间:2018-11-21 19:25:33

标签: python sqlalchemy

我正在尝试使用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']

我只想在db1中创建Table1,而在db2中仅创建Table2;但是,我在两个数据库中都得到了这两个表。

总有办法解决这个问题,还是需要在两个单独的文件中创建数据库。

1 个答案:

答案 0 :(得分:2)

您的问题不是由尝试在同一模块中创建两个数据库引起的。而是,您在映射了两个表的同一元数据对象上调用create_all()。例如

print(Base.metadata.tables)

结果:

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

docs关于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']