![](/img/trans.png)
[英]fastapi: mapping sqlalchemy database model to pydantic geojson feature
[英]Update SQLAlchemy ORM existing model from posted Pydantic model in FastAPI?
我想公開一個 API 方法,該方法在 POST 請求中接收數據(用於 beta 注冊 API),並在已經有匹配的 model 時使用新值進行更新。 實現這一目標的最佳方法是什么? 目前我正在這樣做(有點簡化):
我的 ORM model(SqlAlchemy):
class BetaORM(Base):
__tablename__ = "betasignup"
email = Column(EmailType, primary_key=True)
fullname = Column(String, unique=False, index=False, nullable=True)
我的 Pydantic model:
class BetaCreate(BaseModel):
email: EmailStr
fullname: Optional[str]
我的 FastAPI 發布方法:
@app.post("/beta_signup")
def post_beta_signup(beta: schemas.BetaCreate, db: Session = Depends(get_db)):
return create_beta_signup(db=db,signup=beta)
還有我寫的 CRUD 方法:
def create_beta_signup(db: Session, signup: schemas.BetaCreate):
db_beta = schemas.BetaORM(**signup.dict())
ret_obj = db.merge(db_beta)
db.add(ret_obj)
db.commit()
return ret_obj
使用 merge() 的一個問題是它依賴於與主鍵匹配,直接針對 email 地址 - 我寧願使用代理鍵,這樣我就可以擁有禁用/刪除功能而不是被迫擁有在數據庫級別對 email 地址的唯一約束。
基於FastAPI sqlalchemy 演示應用程序,這是解決此問題的方法:
def update_user(db: Session, user: PydanticUserUpdate):
"""
Using a new update method seen in FastAPI https://github.com/tiangolo/fastapi/pull/2665
Simple, does not need each attribute to be updated individually
Uses python in built functionality... preferred to the pydintic related method
"""
# get the existing data
db_user = db.query(User).filter(User.id == user.id).one_or_none()
if db_user is None:
return None
# Update model class variable from requested fields
for var, value in vars(user).items():
setattr(db_user, var, value) if value else None
db_user.modified = modified_now
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
此方法使用 SQLAlchemy 聲明性 model 定義(不是 Gabriel Cappelli 使用的命令式定義)
我使用這種方法在基於 FastAPI 的應用程序中進行 crud 更新。 現有數據保持不變,並覆蓋新的更新值。 修改后的日期時間已更新(但為了便於測試,此值是固定的)。
希望能幫助到你。 (我花了太長時間才弄清楚這一點。)
如果您使用 MySQL 和 SQLAlchemy >= 1.2,您可以使用INSERT...ON DUPLICATE KEY UPDATE
使用 SQLAlchemy。
from sqlalchemy.dialects.mysql import insert
insert_stmt = insert(my_table).values(
id='some_existing_id',
data='inserted value')
on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
data=insert_stmt.inserted.data,
status='U'
)
conn.execute(on_duplicate_key_stmt)
有關文檔的更多信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.