[英]Sqlalchemy utilize foreign key in table creation
I've began learning sqlalchemy and the script below shows how far I've gotten.我已经开始学习 sqlalchemy,下面的脚本显示了我已经走了多远。 I've created a class to start the database, a class that creates a table containing games and their ID's and a class that is used to create tables for each individual external data source.
我创建了一个 class 来启动数据库,一个 class 创建一个包含游戏及其 ID 的表,以及一个用于为每个单独的外部数据源创建表的 class。
I realized I need to incorporate foreign keys but upon doing so I get the error below.我意识到我需要合并外键,但是这样做后我得到了下面的错误。 It's very confusing because I'm fairly certain the MLBGamelist table was created.
这非常令人困惑,因为我相当确定 MLBGamelist 表已创建。 Any help on this wuld be greatly appreciated.
对此的任何帮助将不胜感激。
sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'CaesarsGamelist.game_ref' could not find table 'MLBGamelist' with which to generate a foreign key to target column 'game_ref'
class DBControl:
def __init__(self,mem):
print('>>>> [MAIN]: INITIALIZING MAIN DATABASE CONNECTION')
self.engine = create_engine(memory[mem], echo=False)
self.inspector = inspect(self.engine)
self.db_connection = self.engine.connect()
self.create_session = sessionmaker(bind=self.engine)
class GamelistMLBControl:
def __init__(self,book,db_control):
self.table_name = f'{book}Gamelist'
self.db_control = db_control
def commit_entry(self,site_data):
write_session = scoped_session(self.db_control.create_session)
insert_stmt = insert(self.check_table()).values(site_data)
write_session.execute(insert_stmt)
write_session.commit()
write_session.remove()
def check_table(self):
metadata = MetaData(bind=self.db_control.engine)
if self.table_name not in self.db_control.inspector.get_table_names():
table_name = Table(
str(self.table_name),
metadata,
Column("event_id", Integer, primary_key=True),
Column("game_ref", String),
Column("game_datetime", Integer),
Column("book", String),
)
metadata.create_all(self.db_control.db_connection)
print(f'> [{self.table_name}]: Table created')
else:
metadata.reflect(self.db_control.engine)
print(f'> [{self.table_name}]: Table exists')
return Table(table_name, metadata, autoload=True)
class GamelistControl:
def __init__(self,book,db_control):
self.table_name = f'{book}Gamelist'
self.db_control = db_control
def commit_entry(self,site_data):
write_session = scoped_session(self.db_control.create_session)
insert_stmt = insert(self.check_table()).values(site_data)
write_session.execute(insert_stmt)
write_session.commit()
write_session.remove()
def check_table(self):
metadata = MetaData(bind=self.db_control.engine)
if self.table_name not in self.db_control.inspector.get_table_names():
table_name = Table(
str(self.table_name),
metadata,
Column("event_id", Integer, primary_key=True),
Column("game_ref", String, ForeignKey('MLBGamelist.game_ref')),
Column("game_datetime", Integer, ForeignKey('MLBGamelist.game_datetime')),
Column("book", String),
)
metadata.create_all(self.db_control.db_connection)
print(f'> [{self.table_name}]: Table created')
else:
metadata.reflect(self.db_control.engine)
print(f'> [{self.table_name}]: Table exists')
return Table(table_name, metadata, autoload=True)
SQLAlchemy stores details of tables in MetaData
objects when a table is created or reflected. SQLAlchemy 在创建或反映表时将表的详细信息存储在
MetaData
对象中。 Binding an engine to a MetaData
object does not in itself cause any table details to be stored.将引擎绑定到
MetaData
本身不会导致存储任何表详细信息。 In the code in the question, each class creates a separate MetaData
instance, hence the error occurs because the Metadata
instance created in GamelistControl
doesn't have details of the table created in GamelistMLBControl
.在问题的代码中,每个 class 创建一个单独的
MetaData
实例,因此发生错误是因为在GamelistMLBControl
创建的Metadata
实例没有在GamelistControl
创建的表的详细信息。
To solve the problem, either call metadata.reflect()
after creating the MetaData
instance in GamelistControl
or create a single MetaData
as an attribute of DBControl
and use that to create tables in both classes.要解决这个问题,要么在
GamelistControl
中创建MetaData
实例后调用metadata.reflect()
,要么创建单个MetaData
作为DBControl
的属性,并使用它在两个类中创建表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.