我正在尝试使用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;但是,我在两个数据库中都得到了这两个表。
总有办法解决这个问题,还是需要在两个单独的文件中创建数据库。
答案 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']