让 SQLAlchemy-ImageAttach 与 Pydantic 一起工作时遇到问题:有例子吗?
Trouble getting SQLAlchemy-ImageAttach to work with Pydantic: Any Examples?
我正在尝试使用 SQLAlchemy-ImageAttach with Pydantic and FastAPI,但不太成功。
我以前从来没有用过SQLAlchemy-ImageAttach,我肯定是用错了。我似乎无法保存任何图像,但我可以让所有非图像方面正常工作。 (我已经成功整合了SQLAlchemy + Pydantic + FastAPI,还有also great examples可以帮忙。)
我正在尝试制作一个由数据库支持的网站,用户可以在其中创建测验问题并将图像与问题一起嵌入。下面的代码突出显示了与测验问题 + 图片相关的部分。
我的 Pydantic models/schemas:
from typing import List, Optional
from pydantic import BaseModel
class QuestionPictureBase(BaseModel):
pass
class QuestionPicture(QuestionPictureBase):
id: int
question_id: int
class Config:
orm_mode = True
class QuestionBase(BaseModel):
header: str
details: str
class QuestionCreate(QuestionBase):
pass
class Question(QuestionBase):
id: int
creator_id: int
pictures: List[QuestionPicture] = []
class Config:
orm_mode = True
SQLAlchemy 模型:
from sqlalchemy import create_engine, Boolean, Column, ForeignKey, Integer, String, Text
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy_imageattach.entity import Image, image_attachment
SQLALCHEMY_DATABASE_URL = "sqlite:///sqlalch.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Question(Base):
__tablename__ = "questions"
id = Column(Integer, primary_key=True, index=True)
header = Column(String, index=True)
details = Column(String, index=True)
creator_id = Column(Integer, ForeignKey("users.id"))
*** pictures = image_attachment("QuestionPicture", uselist=True) ***
creator = relationship("User", back_populates="questions")
class QuestionPicture(Base, Image):
"""Model for pictures associated with the question."""
__tablename__ = "question_pictures"
id = Column(Integer, primary_key=True)
# Not sure if the question ID should also be a unique identifier
# question_id = Column(Integer, ForeignKey("questions.id"), primary_key=True)
question_id = Column(Integer, ForeignKey("questions.id"))
question = relationship("Question", back_populates="pictures")
突出显示的行
*** pictures = image_attachment("QuestionPicture", uselist=True) ***
是我认为我做错事的地方。但是我不太确定我应该做什么。
我只是不太明白应该如何使用 image_attachment
函数调用。它似乎在 SQLAlchemy-ImageAttach 文档中“自动”工作,我不明白。
有没有人有任何使用 SQLAlchemy-ImageAttach + Pydantic (+ FastAPI) 的工作示例。最让我困惑的是与 Pydantic 的互动。
更新
有人要求提供更多详细信息,但要提出的问题太多了。因此,我创建了一个 git 分支,其中包含所有后端,但仅包含称为 temp
和 pushed it to a public GitHub repo.
的后端
解决方案
@r-m-n
下面的解决方案让我顺利完成了部分工作,但我的主要问题是我不清楚我的 pictures
数据库需要包含什么。
在查看了一些错误输出并阅读了源代码之后,我发现 the needed structure here 并调整了我的 alembic(数据库版本控制)代码如下:
def upgrade():
op.create_table(
"question_pictures",
sa.Column("id", sa.Integer, primary_key=True, index=True),
sa.Column(
"question_id", sa.Integer, sa.ForeignKey("questions.id"), nullable=False
),
sa.Column("width", sa.Integer, nullable=False),
sa.Column("height", sa.Integer, nullable=False),
#: (:class:`str`) The mimetype of the image
#: e.g. ``'image/jpeg'``, ``'image/png'``.
sa.Column("mimetype", sa.String(255), nullable=False),
sa.Column("original", sa.Boolean, nullable=False, default=False),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
)
在上面的列表中,缺少的是 width
、height
、original
、mimetype
和 created_at
,而我并不知道我需要添加。
(上面的sa
是sqlalchemy
的缩写,op
是alembic.op
的缩写。)
SQLAlchemy-ImageAttach 在创建关系时默认使用 lazy=dynamic
参数:https://github.com/dahlia/sqlalchemy-imageattach/blob/master/sqlalchemy_imageattach/entity.py#L148。所以 question.pictures
returns 一个 Query
对象而不是一个列表,你需要调用 question.pictures.all()
来获取图片列表。
您可以设置lazy=select
或lazy=joined
。查看更多关于惰性参数 here.
pictures = image_attachment("QuestionPicture", uselist=True, lazy='select')
我正在尝试使用 SQLAlchemy-ImageAttach with Pydantic and FastAPI,但不太成功。
我以前从来没有用过SQLAlchemy-ImageAttach,我肯定是用错了。我似乎无法保存任何图像,但我可以让所有非图像方面正常工作。 (我已经成功整合了SQLAlchemy + Pydantic + FastAPI,还有also great examples可以帮忙。)
我正在尝试制作一个由数据库支持的网站,用户可以在其中创建测验问题并将图像与问题一起嵌入。下面的代码突出显示了与测验问题 + 图片相关的部分。
我的 Pydantic models/schemas:
from typing import List, Optional
from pydantic import BaseModel
class QuestionPictureBase(BaseModel):
pass
class QuestionPicture(QuestionPictureBase):
id: int
question_id: int
class Config:
orm_mode = True
class QuestionBase(BaseModel):
header: str
details: str
class QuestionCreate(QuestionBase):
pass
class Question(QuestionBase):
id: int
creator_id: int
pictures: List[QuestionPicture] = []
class Config:
orm_mode = True
SQLAlchemy 模型:
from sqlalchemy import create_engine, Boolean, Column, ForeignKey, Integer, String, Text
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy_imageattach.entity import Image, image_attachment
SQLALCHEMY_DATABASE_URL = "sqlite:///sqlalch.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Question(Base):
__tablename__ = "questions"
id = Column(Integer, primary_key=True, index=True)
header = Column(String, index=True)
details = Column(String, index=True)
creator_id = Column(Integer, ForeignKey("users.id"))
*** pictures = image_attachment("QuestionPicture", uselist=True) ***
creator = relationship("User", back_populates="questions")
class QuestionPicture(Base, Image):
"""Model for pictures associated with the question."""
__tablename__ = "question_pictures"
id = Column(Integer, primary_key=True)
# Not sure if the question ID should also be a unique identifier
# question_id = Column(Integer, ForeignKey("questions.id"), primary_key=True)
question_id = Column(Integer, ForeignKey("questions.id"))
question = relationship("Question", back_populates="pictures")
突出显示的行
*** pictures = image_attachment("QuestionPicture", uselist=True) ***
是我认为我做错事的地方。但是我不太确定我应该做什么。
我只是不太明白应该如何使用 image_attachment
函数调用。它似乎在 SQLAlchemy-ImageAttach 文档中“自动”工作,我不明白。
有没有人有任何使用 SQLAlchemy-ImageAttach + Pydantic (+ FastAPI) 的工作示例。最让我困惑的是与 Pydantic 的互动。
更新
有人要求提供更多详细信息,但要提出的问题太多了。因此,我创建了一个 git 分支,其中包含所有后端,但仅包含称为 temp
和 pushed it to a public GitHub repo.
解决方案
@r-m-n
下面的解决方案让我顺利完成了部分工作,但我的主要问题是我不清楚我的 pictures
数据库需要包含什么。
在查看了一些错误输出并阅读了源代码之后,我发现 the needed structure here 并调整了我的 alembic(数据库版本控制)代码如下:
def upgrade():
op.create_table(
"question_pictures",
sa.Column("id", sa.Integer, primary_key=True, index=True),
sa.Column(
"question_id", sa.Integer, sa.ForeignKey("questions.id"), nullable=False
),
sa.Column("width", sa.Integer, nullable=False),
sa.Column("height", sa.Integer, nullable=False),
#: (:class:`str`) The mimetype of the image
#: e.g. ``'image/jpeg'``, ``'image/png'``.
sa.Column("mimetype", sa.String(255), nullable=False),
sa.Column("original", sa.Boolean, nullable=False, default=False),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
)
在上面的列表中,缺少的是 width
、height
、original
、mimetype
和 created_at
,而我并不知道我需要添加。
(上面的sa
是sqlalchemy
的缩写,op
是alembic.op
的缩写。)
SQLAlchemy-ImageAttach 在创建关系时默认使用 lazy=dynamic
参数:https://github.com/dahlia/sqlalchemy-imageattach/blob/master/sqlalchemy_imageattach/entity.py#L148。所以 question.pictures
returns 一个 Query
对象而不是一个列表,你需要调用 question.pictures.all()
来获取图片列表。
您可以设置lazy=select
或lazy=joined
。查看更多关于惰性参数 here.
pictures = image_attachment("QuestionPicture", uselist=True, lazy='select')