繁体   English   中英

Sqlalchemy 在表创建中使用外键

[英]Sqlalchemy utilize foreign key in table creation

我已经开始学习 sqlalchemy,下面的脚本显示了我已经走了多远。 我创建了一个 class 来启动数据库,一个 class 创建一个包含游戏及其 ID 的表,以及一个用于为每个单独的外部数据源创建表的 class。

我意识到我需要合并外键,但是这样做后我得到了下面的错误。 这非常令人困惑,因为我相当确定 MLBGamelist 表已创建。 对此的任何帮助将不胜感激。

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 在创建或反映表时将表的详细信息存储在MetaData对象中。 将引擎绑定到MetaData本身不会导致存储任何表详细信息。 在问题的代码中,每个 class 创建一个单独的MetaData实例,因此发生错误是因为在GamelistMLBControl创建的Metadata实例没有在GamelistControl创建的表的详细信息。

要解决这个问题,要么在GamelistControl中创建MetaData实例后调用metadata.reflect() ,要么创建单个MetaData作为DBControl的属性,并使用它在两个类中创建表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM