簡體   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