SQLAlchemy:为关系列赋值

Posted

技术标签:

【中文标题】SQLAlchemy:为关系列赋值【英文标题】:SQLAlchemy: Assign value to a relationship column 【发布时间】:2019-12-13 12:54:02 【问题描述】:

我已经定义了这些 SQLAlchemy 模型:

class Person(db.Model):
    id = db.Column(db.Integer, primar_key=True)
    pets = db.relationship("Pet", backref="person", lazy=True)

class Pet(db.Model):
    id = db.Column(db.Integer, primar_key=True)
    name = db.Column(db.String(120))
    person = db.Column(db.Integer, db.ForeignKey("person.id"))

我正在尝试分配/覆盖 Person.pets 以供以后使用(但不更新 db 中的值)。

person_with_temporary_pet = 1: ["Max", "Charlie", "Cooper"], 2: ["Buddy", "Rocky", "Millo"]
overwrited_person = []

for id, name in person_with_temporary_pet.items():
    person = Person.query.get(id)
    person.pets = name
    overwrited_person.append(person)

这将导致AttributeError: 'str' object has no attribute '_sa_instance_state'


仅供参考,我想将 overwrited_person 转储到 Marshmallow 架构中:

class PersonSchema(ma.ModelSchema):
    class Meta:
        model = Person

person_schema = PersonSchema(many=True)   

【问题讨论】:

【参考方案1】:

你在错误的类中定义了你的宠物关系,你需要把它放在宠物类本身。 person_obj.pets 包含一个 Pet 对象列表,而您正尝试为其分配字符串列表。要在您的场景中工作,您可以更改您的 for 循环代码,如下所示:

for id, name in person_with_temporary_pet.items():
    person = Person.query.get(id)
    person.pets = Pet.query.filter(Pet.name.in_(name)).all()
    overwrited_person.append(person)

希望这会有所帮助!

【讨论】:

【参考方案2】:

这可能与this question有关。

在您的情况下,您在 Person 中定义 Pets 模式,但尝试传递字符串值数组而不是对象。

【讨论】:

以上是关于SQLAlchemy:为关系列赋值的主要内容,如果未能解决你的问题,请参考以下文章

Postgres中'money'和'OID'的sqlalchemy等效列类型是啥?

python SQLAlchemy

使用 sqlalchemy 实现“软删除”系统

python的一些开源库

sqlalchemy 简单使用

Python 开源项目大杂烩