sqlalchemy:创建和获取一对多关系时遇到问题,为什么我得到 InstrumentedList 而不是 List

sqlalchemy: troubles creating and getting one to many relationship, Why do I get InstrumentedList instead of List

我真的是使用 SqlAlchemy 的新手,现在我正在使用 fastAPI,基本上我需要创建一个可以有多个嵌套参数的指标模型

这是我的代码

class Indicator(Base):
    __tablename__ = "indicator"
    id = Column(Integer, primary_key=True, autoincrement=True, index=True)
    name = Column(String, unique=True, nullable=False)
    indicator_lib_name = Column(String, unique=True, nullable=False)
    properties = relationship("Property", backref="indicator", lazy=True,cascade="all, delete")

class Property(Base):
    __tablename__ = "property"
    id = Column(Integer, primary_key=True, autoincrement=True, index=True)
    name = Column(String, unique=True, nullable=False)
    value = Column(sqlalchemy_utils.ScalarListType, nullable=True)
    indicator_id = Column(Integer, ForeignKey("indicator.id", ondelete="CASCADE"))
    # indicator = relationship("Indicator", back_populates="properties")

from pydantic import BaseModel

class Property(BaseModel):
    id: Optional[int]
    name: str
    value: List[Any]

class IndicatorCreate(BaseModel):
    name: str
    indicator_lib_name: Optional[str]
    properties: List[Property]

# 
# https://dev.to/brandonwallace/one-to-many-relationships-complete-how-to-2nbi
def create_new_indicator(db: Session, indicator: IndicatorCreate):
    indicator_data = indicator.dict()
    properties = []
    if indicator.properties:
        properties = indicator_data.pop("properties", None)

    new_indicator = Indicator(**indicator_data)
    new_indicator.indicator_lib_name = indicator.indicator_lib_name or indicator.name

    db.add(new_indicator)
    db.commit()
    db.refresh(new_indicator)

    for prpty in properties:
        # prpty["indicator"] = new_indicator
        property_model = Property(**prpty, indicator=new_indicator)
        db.add(property_model)
        db.commit()
        db.refresh(property_model)

    db.refresh(new_indicator)
    return new_indicator
@indicators_router.post("/", response_model=IndicatorBase)
def create_indicator(indicator: IndicatorCreate, db: Session = Depends(get_db)):
    indicator_new = create_new_indicator(db, indicator)
    print("indicator ", indicator_new)
    return indicator_new
data = {
    "name": "adx",
    "indicator_name": "adx",
    "properties": [{"name": "range", "value": [2]}],
}

def test_create_indicator(client):
    global data
    response = client.post("/indicators/", json.dumps(data))
    data = response.json()
    print(data)
    assert response.status_code == 200
    assert data["name"] == "adx"
    assert data["id"] == 1
    assert len(data["properties"]) == 1

错误是

>               raise ValidationError(errors, field.type_)
E               pydantic.error_wrappers.ValidationError: 1 validation error for IndicatorBase
E               response -> properties -> 0
E                 value is not a valid dict (type=type_error.dict)

当我调试代码时,我可以看到正确填充的属性,它正在获取数据,但结构是 InstrumentedList 而不是 List,为什么?如何将其转换为列表或更好的问题:哪种方法更好?

我创建指标和参数的方式更好吗?还是有更简洁的方式?

非常感谢你们,希望你们能在我使用 SQLAlchemy 的第一步中帮助我

您的 Property 架构未定义为可从 ORM 加载(即在源对象中使用 .foo 而不是 ['foo'])。

您可以通过添加

来更改它
class Config: 
    orm_mode = True 

在您的架构中 class。由于这不存在,pydantic 期望类似字典(即可以通过字典查找来解析属性)。