【问题标题】:How to add images to models (tables) and save it to database in FastAPI framework?如何将图像添加到模型(表)并将其保存到 FastAPI 框架中的数据库?
【发布时间】:2020-07-21 15:30:07
【问题描述】:

我处理 FastAPI 并且无法弄清楚如何简化(从我使用 django 的经验来看)的事情 - 将带有图像的产品添加到数据库中。据我了解,图像应该存储在静态文件夹中,并且只有指向它的链接应该存储在数据库中。 根据官方文档的信息,我添加了这个方案

schema.py

from pydantic import BaseModel, HttpUrl
from typing import Optional


class ProductImageSchema(BaseModel):
    url: HttpUrl
    name: str


class ProductSchema(BaseModel):
    name: str
    description: Optional[str] = None
    image: Optional[ProductImage] = None

我正在使用 SQLAlchemy。现在我的第一个问题是如何正确描述产品模型。 models.py

product = Product(
    "product",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("name", String(50)),
    Column("description", String(50)),
    Column(....str_or_url..????) # field with relation with image,
)

目前还不清楚如何创建产品对象的新实例。比如……

crud.py

async def post(payload: ProductSchema, file: UploadFile = File(...)):
    content = await file.read()
    if file.content_type not in ['image/jpeg', 'image/png']:
        raise HTTPException(status_code=406, detail="Only .jpeg or .png  files allowed")
    file_name = f'{uuid.uuid4().hex}{ext}'
    async with aiofiles.open(file_name, "wb") as f:
        await f.write(content)
    query = product.insert().values(title=payload.name, description=payload.description, image=????????)
    return await database.execute(query=query)

【问题讨论】:

    标签: python sqlalchemy fastapi pydantic


    【解决方案1】:

    你的方法是正确的。据我所知,图像以及其他用户的文件都存储在静态(或其他)文件夹中,并且参考保存在数据库中。在某些情况下,文件名(可能带有扩展名)存储在表中,而在其他情况下,尤其是在分布式应用程序中,会存储整个 URL。

    您的crud.py 文件似乎是正确的。只需将查询中的 image 参数更改为您使用的 URL 或文件名。 确保没有其他用户已经插入同名(和扩展名)的文件,否则您将覆盖您用户的文件!

    回到你的问题,

    我将进一步改进schema.py 文件中的ProductImageSchema,如下所示

    from datetime import datetime
    class ProductImageSchema(BaseModel):
        url: HttpUrl
        name: str
        type: str
        creation_date: datetime.datetime = datetime.now()
    

    由于您没有指定数据模型(即数据库结构),我只能根据您编写的内容进行推断。如果我的推断是正确的,那么一个产品可能有多个图像,因此您需要一个用于产品的表格和一个用于图像的表格。我的猜测是产品之间不共享图像,否则您将需要 3 个表。

    虽然这段代码看起来不像有效的 SQLAlchemy 代码,但这里有一个示例说明您可以做什么

    product = Product(
        "product",
        metadata,
        Column("id", Integer, primary_key=True),
        Column("name", String(50)),
        Column("description", String(50))
    )
    images = Image(
        "image",
        metadata,
        Column("product", Integer, ForeignKey(Product.id), primary_key=True,),
        Column("name", String(50), primary_key=True),
        Column("filetype", String(50))
    )
    

    但我不确定这是有效的 SQLAlchemy 代码,因为您发布的内容看起来也不正确。无论如何,我希望这足以理解这个想法。

    【讨论】:

    • 如何使用上述概念更新个人资料图片?我已经问过这个“stackoverflow.com/questions/64474061/…
    • @HimalAcharya 您的问题与此无关,因为您使用的是 nosql(无模式)数据库而不是关系数据库。 SQLAlchemy 不起作用,因此不在此问题的主题范围内
    • 我在我的项目中相应地应用了上述逻辑来添加学生(它有效)。我只想知道如何使用 SQLAlchemy 更新上述示例中的文件,仅 CRUD 操作
    • 在这种情况下,图像被上传到静态服务器。您必须以原子方式更新图像和数据。在数据库中只会有文件名和类型的引用,而实际的图像将存储在静态服务器中
    • 我能得到上面例子的更新操作码吗?虽然我应用上述逻辑,但每次它都会在正文中给出解析错误。
    猜你喜欢
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    相关资源
    最近更新 更多