【问题标题】:SQLAlchemy: ForeignKey across schemasSQLAlchemy:跨模式的 ForeignKey
【发布时间】:2021-11-03 23:35:18
【问题描述】:

在我的postgres 服务器中,我们有一个数据库database 有2 个模式:publicapipublic 有几个表,我需要在api 中创建一个表,并使用public 中名为model 的表的外键。 所以它是:

-Schemas
--public
---tables
----models
--api
---tables

使用 SQLAlchemy 我有以下课程:

from sqlalchemy import create_engine, MetaData, Table, Column

class __PostgresService:
  def __init__(self):
    self.__client = create_engine("postgresql://postgres@localhost:5432/database")
    metadata = MetaData(self.__client, schema="public")
    self.__table = Table("training", metadata,
                         Column("id", String, primary_key=True, nullable=False),
                         Column("model_id", ForeignKey("model.id"), nullable=False),
                         schema="api")
    metadata.create_all()

postgres_service = __PostgresService()

但是在启动时我收到以下错误:

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'training.model_id' could not find table 'public.model' with which to generate a foreign key to target column 'id'

它似乎确实在寻找正确的东西但找不到它?我对为什么会发生这种情况感到非常困惑,特别是因为错误是指找不到“public”,这是由postgres 默认创建的,而不是我在 pgAdmin 中创建的“api”。 我是否缺少一些关键配置?

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    您得到的错误意味着您正在尝试创建一个引用 SQLAlchemy 不知道的表的外键。您可以通过创建与描述引用表的相同MetaData 关联的Table 来告诉sqlalchemy。您也可以使用 sqlalchemy 的 reflection capabilities 来执行此操作。例如:

    from sqlalchemy import create_engine, MetaData, Table, Column
        
    class __PostgresService:
        def __init__(self):
            self.__client = create_engine("postgresql://postgres@localhost:5432/database")
            metadata = MetaData(self.__client, schema="public")
            metadata.reflect(schema="public", only=["model"])
            self.__table = Table("training", metadata,
                    Column("id", String, primary_key=True, nullable=False),
                    Column("model_id", ForeignKey("model.id"), nullable=False),
                    schema="api")
            metadata.create_all()
    
            postgres_service = __PostgresService()
    
    

    默认情况下,MetaData.create_all() 会在创建表之前先检查表是否存在,但您也可以指定要创建的确切表:metadata.create_all(tables=[self.__table])

    【讨论】:

    • 谢谢,这正是我所需要的。如果表存在,我只需要创建它,这样就可以了。
    猜你喜欢
    • 1970-01-01
    • 2021-08-16
    • 2016-04-29
    • 2020-04-13
    • 2015-08-08
    • 1970-01-01
    • 2011-11-25
    • 2015-06-29
    • 2013-08-29
    相关资源
    最近更新 更多