5

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

架构.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。现在我的第一个问题是如何正确描述产品模型。 模型.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)
4

1 回答 1

0

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

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

回到你的问题,

我将使用以下内容进一步改进文件中ProductImageSchemaschema.py

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 代码,因为您发布的内容看起来也不正确。无论如何,我希望这足以理解这个想法。

于 2020-07-21T19:56:38.507 回答