Использование аннотации ввода в теле функции FastAPI, когда тип возвращаемого значения является классом ORM SQLalchemy.Python

Программы на Python
Anonymous
Использование аннотации ввода в теле функции FastAPI, когда тип возвращаемого значения является классом ORM SQLalchemy.

Сообщение Anonymous »

Я использовал SQLalchemy и FastAPI на Python 3.10 и пытался внедрить типизацию в свой проект, но обнаружил, что есть кое-что, с чем я не могу справиться.
Согласно официальной документации FastAPI, я могу привести пример кода, который несовместим с проверкой ввода:

Код: Выделить всё

import uvicorn
from fastapi import Depends, FastAPI
from pydantic import BaseModel
from sqlalchemy import Column, create_engine
from sqlalchemy import Integer, String
from sqlalchemy.orm import sessionmaker, Session, declarative_base

app = FastAPI()

Base = declarative_base()

class User(BaseModel):
id: int
passwd: str

engine = create_engine("sqlite:///./example.db")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
class Users(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
passwd = Column(String(20))
Base.metadata.create_all(bind=engine)

@app.post("/register/")
async def register(user: User, db: Session = Depends(get_db)):
db_user = Users(id=user.id, passwd=user.passwd)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
@app.post("/login/")
async def login(user: User, db: Session = Depends(get_db)):
db_user = db.query(Users).filter(Users.id == user.id).first()
if db_user is None or db_user.passwd != user.passwd:  # THIS LINE TYPING ERROR
return {"status": "failed"}
else:
return {"status": "success"}

if __name__ == "__main__":
uvicorn.run("example:app")
Чтобы сделать код более понятным, я поясню его. Я создал пример базы данных и использовал ORM для создания таблицы с именем пользователей, а также создал API для входа и регистрации. Здесь все просто для примера. Да, этот код работает отлично, но программа проверки ввода сообщает в строке, которую я прокомментировал, есть ошибка ввода.
Чтобы исправить это, я поискал в документации SQLalchemy и нашел решение, изменить столбец в mapped_column из sqlalchemy.orm. Чтобы добавить больше аннотаций к вводу и улучшить его, я изменил код следующим образом:

Код: Выделить всё

from typing import Generator, Any
import uvicorn
from fastapi import Depends, FastAPI
from pydantic import BaseModel
from sqlalchemy import create_engine
from sqlalchemy import Integer, String
from sqlalchemy.orm import sessionmaker, Session, declarative_base, mapped_column

app = FastAPI()

Base = declarative_base()

class User(BaseModel):
id: int
passwd: str

engine = create_engine("sqlite:///./example.db")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def get_db() -> Generator[Session, Any, None]:
db = SessionLocal()
try:
yield db
finally:
db.close()

class Users(Base):
__tablename__ = "users"
id = mapped_column(Integer, primary_key=True, index=True)
passwd = mapped_column(String(20))
Base.metadata.create_all(bind=engine)
@app.post("/register/")
async def register(user: User, db: Session = Depends(get_db)) -> Users: # ERROR THIS LINE
db_user = Users(id=user.id, passwd=user.passwd)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user

@app.post("/login/")
async def login(user: User, db: Session = Depends(get_db)) -> dict[str, str]:
db_user = db.query(Users).filter(Users.id == user.id).first()
if db_user is None or db_user.passwd != user.passwd:
return {"status": "failed"}
else:
return {"status": "success"}

if __name__ == "__main__":
uvicorn.run("example:app")
Теперь кажется, что все проверки ввода выполняются правильно, нет ни ошибок, ни предупреждений. Однако код не запустится, поскольку строка, которую я прокомментировал, завершилась ошибкой, в которой говорилось, что «Пользователи» не являются допустимой моделью Pydantic.
Возможно, я неправильно понял pydantic и перепутал его с типизацией, но Я просто не пойму, поскольку db_user - это ПРОСТО объект Users, а не объект User. Да, я могу использовать -> Пользователь, чтобы скрыть ошибку, но программа проверки текста не удовлетворена этим. Я также могу использовать в декораторе response_model = User, что на самом деле я и использую, но является ли это лучшим способом справиться с этим? Могу ли я просто создать класс объектов, который удовлетворяет требованиям проверки ввода и поддерживается ORM SQLalchemy, и поместить его после ->?
Я пытался прочитать документацию SQLalchemy.
из https://docs.sqlalchemy.org/en/20/orm/dataclasses.html Я нашел сопоставленный_столбец и решил некоторые проблемы, но другие существующие проблемы не были решены, поскольку я не нашел ничего полезного.
Все документы, которые я нашел, просто избегают использования объекта Pydantic или SQLalchemy в FastAPI, а создают аналогичный объект на основе BaseModel. в pydantic в качестве возвращаемого типа, но я получаю ошибку типа, сообщающую, что два объекта несовместимы, когда я помещаю это после ->.
Если вы спросите, почему Я просто делаю это...
Наша группа пытается импортировать ввод текста в проверку кода и не допускает ошибок ввода, а тип всех переменных и функций должен быть отмечен.
Буду более чем благодарен за то, что вы читаете и даете мне советы!

Подробнее здесь: https://stackoverflow.com/questions/771 ... is-a-sqlal

Вернуться в «Python»