【问题标题】:Insert list of child objects when inserting parent in sqlalchemy在 sqlalchemy 中插入父对象时插入子对象列表
【发布时间】:2023-03-08 09:52:01
【问题描述】:

我有一个 SQLAlchemy 父子类,如下所示。两者的关系是一对多的关系。

class Parent():
    systemName = Column(type_=String(100), primary_key=True)
    startDate = Column(type_=DateTime)
    childs = relationship("Child")

class Child():
    systemName = Column(type_=String(100), primary_key=True)
    name = Column(type_=String(100))
    parentSystemName = Column(
        String(100),
        ForeignKey("Parents", ondelete="CASCADE")
    )

我已将“孩子”作为“孩子”列表包含在响应模型中。因此,当我从数据库中为父级获取数据时,响应如下 -

{
   "systemName":"62259fd1_79b5_42b9_8381_3c0f9a6be322",
   "startDate":"2020-09-12T19:24:58.357000",
   "childs":[
      {
         "systemName":"ee16d7df-748f-4766-8233-a2997adb09dd",
         "name":"Child1",
         "parentSystemName":"62259fd1_79b5_42b9_8381_3c0f9a6be322"
      },
      {
         "systemName":"89306f60-9ec2-497a-a18c-8e2bebb682ee",
         "name":"Child2",
         "parentSystemName":"62259fd1_79b5_42b9_8381_3c0f9a6be322"
      }
   ]
}

我想知道如何使用与上述相同的 JSON 结构(即父母中的孩子列表)并将记录添加到数据库中。

obj_in_data = jsonable_encoder(obj_in)
db_obj = self.model(**obj_in_data)
db.add(db_obj)
db.commit()
db.refresh(db_obj)

目前,当我尝试使用与上述相同的 JSON 结构插入数据时,但出现错误 -

AttributeError: 'dict' 对象没有属性 '_sa_instance_state'

【问题讨论】:

  • 您有什么代码会引发该错误?您是否尝试先初始化 Parent 的实例?喜欢Parent(my_json_obj)?还是你用别的东西?
  • 我已经更新了我的问题并添加了代码。 'jsonable_encoder' 将模型转换为问题中提到的 json,而 db_obj 是父 sqlalchemy 模型实例。第 2 行出现错误。

标签: python sqlalchemy


【解决方案1】:

吹毛求疵:child 的倍数是 children。

您的Parent 期望children 是Child-instances 的列表,但它们当然不是。一种可能的解决方法是采用__init__() 函数并对其进行调整。

class Parent():
    systemName = Column(type_=String(100), primary_key=True)
    startDate = Column(type_=DateTime)
    children = relationship("Child")

    def __init__(*args, **kwargs):
       """Take the `children`, if passed, and cast it into an array of `Child`
       instances, if they are not already"""
       if 'children' in kwargs:
           children = kwargs.pop('children', [])
           kwargs['children'] = [
              Child(**child_or_data) if isinstance(child_or_data), dict) else child_or_data)
              for child_or_data) in children
           ]
       super(self, Parent).__init__(*args, **kwargs)

此代码在创建新的Parent 之前执行,获取子列表,查看它们是否为对象,如果是则将它们转换为Children,然后继续进行其余的初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    相关资源
    最近更新 更多