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 期望类似字典(即可以通过字典查找来解析属性)。
我真的是使用 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 期望类似字典(即可以通过字典查找来解析属性)。