使用 DataClass 方法时如何避免 Sqlalchemy 超出最大递归深度

问题描述 投票:0回答:1

我将 sqlalchemy 类映射为数据类。将数据导出为json,以后给flask使用,非常方便。当导出到 json 时,子类将自动导出为父类中的子类列表,这很棒。 我的问题是当我也想将父对象显示为子类中的字段时。然后就进入无限递归。 我的问题是,是否有某种方法可以在创建 sqlalchemy 关系时映射要选择的列,或者是否有其他方法可以自定义从 sqlalchemy-dataclass 对象导出数据?

使用此代码时,会抛出“超出最大递归深度”错误:

@reg.mapped_as_dataclass
class Parent:
    __tablename__ = 'parent'

    Id: int = db.Column('id', db.Integer, primary_key=True)
    Name: str = db.Column('name', db.String)
    
    ChildrenList: 'Child' = db.relationship('Child', default_factory=list, back_populates='ParentObject')


@reg.mapped_as_dataclass
class Child:
    __tablename__ = 'child'

    Id: int = db.Column('id', db.Integer, primary_key=True)
    ParentId: int = db.Column('parent$id', db.Integer, ForeignKey('parent.id'))
    
    # This field create infinite recursion
    ParentObject: 'Parent' = db.relationship('Parent', back_populates='ChildrenList')
    
    # Can we create something like this to avoid recursion
    # ParentObject: 'Parent' = db.relationship('Parent', back_populates='ChildrenList', select_fields='Id, Name')
    
    # Or like this
    # ParentObject: 'Parent' = db.relationship('Parent', back_populates='ChildrenList', exclude_fields='ChildrenList')


def json_return_example()
    return db.session.query(Parent).all()
python-3.x sqlalchemy flask-sqlalchemy python-dataclasses
1个回答
0
投票

不可能在关系中定义此类行为。你可以:

  • 使用支持所需行为的专用序列化包,例如 Marshmallow 或 Pydantic
  • 编写自己的序列化函数来处理循环引用
  • 仅在一侧定义关系,例如
    Parent
    具有
    children
    属性,但
    Child
    没有父属性。

来自 SQLAlchemy creator的此评论涵盖了相同的内容。

© www.soinside.com 2019 - 2024. All rights reserved.