python - 从 FastAPI 中发布的 Pydantic 模型更新 SQLAlchemy ORM 现有模型?

标签 python sqlalchemy fastapi pydantic

我想公开一个 API 方法,该方法在 POST 请求中接收数据(对于 beta 注册 API),并在已有匹配模型时使用新值进行更新。实现这一目标的最佳方法是什么?目前我正在这样做(有些简化):
我的 ORM 模型(SqlAlchemy):

class BetaORM(Base):
    __tablename__ = "betasignup"
    email = Column(EmailType, primary_key=True)
    fullname = Column(String, unique=False, index=False, nullable=True)
我的 Pydantic 模型:
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() 的一个问题是它依赖于与主键的匹配,直接针对电子邮件地址 - 我更愿意使用 surrogate key相反,这样我就可以拥有禁用/删除功能,而不会被迫在数据库级别对电子邮件地址进行唯一约束。

最佳答案

基于 FastAPI sqlalchemy demo application ,这是解决这个问题的方法:

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 声明式模型定义(不是 Gabriel Cappelli 使用的命令式定义)
Full source code
我使用这种方法在基于 FastAPI 的应用程序中对 crud 进行更新。现有数据保持不变,新的更新值被覆盖。修改的日期时间被更新(但为了便于测试,这个值是固定的)。
希望能帮助到你。 (我花了太长时间弄清楚这一点。)

关于python - 从 FastAPI 中发布的 Pydantic 模型更新 SQLAlchemy ORM 现有模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63143731/

相关文章:

python - 我可以让 FastAPI 端点接收 json 或文件吗

python - 使用 Matplotlib 和 NumPy 在图像上绘制圆圈

python - UBER API 上的行程历史价格

c++ - 带子类的django循环

python - 如何使用 HTTP Digest 进行身份验证?

python - 如何在 fastapi 的 pydantic 模型中允许 List 作为查询参数而不是 requestbody

python - 如何在 Python 中链接多个 re.sub() 命令

sql - 奇怪的 SQL 更新查询

python - SQLAlchemy - 编写子计数的混合方法

python - 为什么 FreezeGun 不能使用 SQLAlchemy 默认值?