微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有数据类和 postgres db 的 SQLAlchemy 不能使用外键,我该如何定义关系?

如何解决带有数据类和 postgres db 的 SQLAlchemy 不能使用外键,我该如何定义关系?

我有 2 个表,一个有外键引用到另一个。 我可以手动插入表(从 postgres localhost Web 界面),并且外键引用就在那里并且很好。

然而,当我想通过我的 app.py 做同样的事情时,它似乎不起作用。 我需要 primaryjoin 关系吗?还是 foreginkey 关系?

我有 2 个 python 类(每个 sql一个,这些表已经作为 postgres db 启动的一部分进行了初始化),“class”表有一个基于 person_name 的“person”表的外键引用。 我只想通过将 person_name 和 class_list 值插入到我的主 app.py

来填充我的 postgres 数据库中的两个表

sql 表定义:


CREATE TABLE persontable(
   person_id INT GENERATED ALWAYS AS IDENTITY,person_name VARCHAR(255) NOT NULL UNIQUE,PRIMARY KEY(person_id)
   
);

#class_list is just a list of strings
#class will reference person_name as FK,not the person_id

CREATE TABLE class(
   class_id INT GENERATED ALWAYS AS IDENTITY,person_name VARCHAR(255),class_list VARCHAR NOT NULL,PRIMARY KEY(class_id),CONSTRAINT fk_person
      FOREIGN KEY(person_name)
      REFERENCES persontable(person_name)
);

@mapper_registry.mapped
@dataclass
class PersonModel:
    __table__ = Table(
        "persontable",mapper_registry.Metadata,Column("person_id",Integer,primary_key=True,autoincrement=True),Column("person_name",String(50),nullable=False,unique=True),)
    person_id: int = field(init=False)
    person_name: str = None


   ############################################
   # do I need this part? I want the PersonModel.person_name to be used for ClassModel.person_name. \
 Or should I just have primaryjoin? what is backref?

    __mapper_args__ = {   # type: ignore
        "properties": {
            "classes": relationship("classModel",backref="persontable")
        }
    }
   ############################################

    def add(self):
        session = Session()
        session.add(self)
        session.commit()

@mapper_registry.mapped
@dataclass
class ClassModel:

    __table__ = Table(
        "class",Column("class_id",ForeignKey("persontable.person_name")),Column("class_list",ARRAY(String))
    )

    class_id: int = field(init=False)
    person_name: str = ''
    class_list: List[str] = field(default_factory=list)

    def add(self):
        session = Session()
        session.add(self)
        session.commit()


因此用户调用 main 函数为:

  1. 将 person_name 和 class_list 传递给函数调用
    addNewUser(person_name="jon",student_class_list={'class1','class2'})
  1. 我的函数会做两件事:
p = PersonModel.add(person_name="jon")
#how do I use the foreign key column created for person p? do I need to explicitly pass it in? or will it be figured out?
ClassModel.add(p,class_list =student_class_list )

如果我在没有映射器属性的情况下运行:

    __mapper_args__ = {   # type: ignore
        "properties": {
            "classes": relationship("classModel",backref="persontable")
        }
    }

它会将项目添加到人员表中(我看到插入了新项目),但类列表不起作用。我收到错误

[ERROR] noreferencedTableError: Foreign key associated with column 'class.person_name' Could not find table 'persontable' with which to generate a foreign key to target column 'person_ '

现在,如果我从上面添加映射器属性 def 并再次运行,我会得到不同的错误

"errorMessage": "entity","errorType": "AttributeError","stackTrace": ["  File \"/var/task/app.py\",line 16,in handler\n    person_id = person.add()\n","  File \"/var/task/person.py\",line 14,in add\n    new_person = models.PersonModel(person_name=self.person_name)\n",

我的整体结构是否正确?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。