0

我想我已经制定了 SQLModel 类(Alembic 确实成功创建了所有表),但我不确定从 POST 端点中的请求数据填充它们的正确方法是什么。

我有一个如下所示的请求有效负载:

{
        "name": "Nicaragua",
        "aka": null,
        "icaoPrefix": "MN",
        "continent": "North America",
        "dialCode": "505",
        "language": "Spanish",
        "isoCode": "NI",
        "isoCode3": "NIC",
        "currencies": [
            {"code": "NIO", "name":"Nicaraguan córdoba", "symbol":"C$"},
            {"code": "USD", "name":"United States Dollar", "symbol":"$"}
        ],
        "timezones": [
            {"code": "CST", "name": "Central Standard Time", "utcOffset": -6},
            {"code": "XXX", "name": "Made Up Time", "utcOffset": 7}
        ],
        "supported": false
    }

为了将其存储在数据库中,我需要使用三个模型——国家、货币和时区

我为多对多关系定义了这些模型(加上两个关联表)

class CountryCurrencyLink(SQLModel, table=True):
    __table_args__ = {"schema": COUNTRY_SCHEMA}
    country_uuid: Optional[str] = Field(
        default=None, foreign_key=f"{COUNTRY_SCHEMA}.country.uuid", primary_key=True
    )
    currency_id: Optional[str] = Field(
        default=None, foreign_key=f"{COUNTRY_SCHEMA}.currency.uuid", primary_key=True
    )


class CurrencyBase(SQLModel):
    code: Annotated[str, Field(min_length=3, max_length=3)]
    name: str
    symbol: str


class Currency(CurrencyBase, table=True):
    __table_args__ = {"schema": COUNTRY_SCHEMA}
    uuid: str = Field(default=lambda: uuid4().hex, primary_key=True)
    countries: List["Country"] = Relationship(
        back_populates="currencies", link_model=CountryCurrencyLink
    )


class CurrencyCreate(CurrencyBase):
    pass


class CountryTimezoneLink(SQLModel, table=True):
    __table_args__ = {"schema": COUNTRY_SCHEMA}
    country_uuid: Optional[str] = Field(
        default=None, foreign_key=f"{COUNTRY_SCHEMA}.country.uuid", primary_key=True
    )
    timezone_id: Optional[str] = Field(
        default=None, foreign_key=f"{COUNTRY_SCHEMA}.timezone.uuid", primary_key=True
    )


class TimezoneBase(SQLModel):
    code: Annotated[str, Field(max_length=3)]
    name: str
    utcOffset: conint(gt=-12, lt=13)


class Timezone(TimezoneBase, table=True):
    __table_args__ = {"schema": COUNTRY_SCHEMA}
    uuid: str = Field(default=lambda: uuid4().hex, primary_key=True)
    countries: List["Country"] = Relationship(
        back_populates="timezones", link_model=CountryTimezoneLink
    )


class TimezoneCreate(TimezoneBase):
    pass


class CountryBase(SQLModel):
    name: str
    aka: Optional[str]
    icaoPrefix: Optional[str]
    continent: str
    dialCode: str
    language: Optional[str]
    isoCode: Annotated[str, Field(max_length=2)]
    isoCode3: Annotated[str, Field(max_length=3)]
    currencies: List[CurrencyBase]
    timezones: List[TimezoneBase]
    supported: bool


class Country(CountryBase, table=True):
    __table_args__ = {"schema": COUNTRY_SCHEMA}
    uuid: str = Field(default=uuid4().hex, primary_key=True)
    currencies: List[Currency] = Relationship(
        back_populates="countries", link_model=CountryCurrencyLink
    )
    timezones: List[Timezone] = Relationship(
        back_populates="countries", link_model=CountryTimezoneLink
    )


class CountryCreate(CountryBase):
    pass


class CountryRead(CountryBase):
    pass

但我的问题是如何处理 POST 请求并创建类和关系。

我试过这个:

@router.post("/")
async def create_country(
    *, session: AsyncSession = Depends(get_session), country: CountryCreate
):

    db_country = Country.from_orm(country)
    session.add(db_country)
    await session.commit()
    await session.refresh(db_country)
    return db_country

我希望from_orm可能已经处理了它,但它看起来不像。我不确定我是否应该采取天真的方法并手动创建它们?或者也许我需要重组我的课程?或者也许有推荐的方法来解决这个问题?

任何帮助表示赞赏!

更新

我试过天真地创造它

@router.post("/")
async def create_country(
    *, session: AsyncSession = Depends(get_session), country: CountryCreate
):
    db_country = Country(
        name=country.name,
        icaoPrefix=country.icaoPrefix,
        continent=country.continent,
        dialCode=country.dialCode,
        language=country.language,
        isoCode=country.isoCode,
        isoCode3=country.isoCode3,
        supported=country.supported,
    )
    db_country.currencies = country.currencies

但是最后一行导致了这个错误 'CurrencyBase' object has no attribute '_sa_instance_state'

4

0 回答 0