Home > Net >  How to add multiple image urls into postgres database using fastAPI?
How to add multiple image urls into postgres database using fastAPI?

Time:06-12

Using the fastAPI multiple uploads function, i am trying to upload images to my server and save the urls as a list to my postgres database. Here is the code i am using to upload the image:

@router.post('/addProductFD', status_code=status.HTTP_201_CREATED, response_model=ShowProduct)
async def create(
    name: str = Form(...),
    price: float = Form(...),
    description: str = Form(...),
    files: List[UploadFile] = File(...),
    db: Session = Depends(get_db),
):
    for file in files:
        try:
            FILEPATH = "./static/product_images/"
            pimage_name = FILEPATH   imghex(file.filename)
            contents = await file.read()
            with open(pimage_name, 'wb') as f:
                f.write(contents)
        except Exception:
            return {"message": "There was an error uploading the file(s)"}
        finally:
            await file.close()
    file_urls = "localhost:8000"   pimage_name[1:]

    new_item = Product(
        name=name,
        price=price,
        description=description,
        imgs_url=file_urls,
    )

    db.add(new_item)
    db.commit()
    db.refresh(new_item)
    {"filenames": [file.filename for file in files]}
    return new_item

When i run this code, it uploads the images and adds the url of just the first image to my database. Please how do i make this code to add the image urls to my database as a list. Here is an example of what i want to do: enter image description here

Below is the schemas.ShowProduct:

class ShowProduct(ProductBase):
    name: str
    description: str
    img: str

    class Config():
        orm_mode = True

Below is my postgresDB models.product:

class Product(Base):
    name = Column(String, nullable=False)
    description = Column(Text, nullable=False)
    owner = relationship("Vendor", back_populates="product")
    img = Column(String)

So i want to recieve a list of the imageurls and add it to the img database column:

Please help!

CodePudding user response:

At first, you need to alter your db model:

class Product(Base):
    name = Column(String, nullable=False)
    description = Column(Text, nullable=False)
    owner = relationship("Vendor", back_populates="product")
    imgs_url = Column(ARRAY(String))

Note: do not forget to generate and apply migration.

then simply pass imgs_url as a list to Product initializer:

new_item = Product(
        name=name,
        price=price,
        description=description,
        imgs_url=["url1", "url2"],
    )

Finally, you can alter your model factory:

class ShowProduct(ProductBase):
    name: str
    description: str
    imgs_url: list[str]

    class Config:
        orm_mode = True

I think you should rethink your design and take imho better approach, with table relationships. So you would create two tables: products (as already defined) and images (new one) which will be connected via foreign key:

class Product(Base):
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    description = Column(Text, nullable=False)
    owner = relationship("Vendor", back_populates="product")
    images = relationship("Image", back_populates="product")
class Image(Base):
    url = Column(String, nullable=False)
    product_id = Column(Integer, ForeignKey("images.id"))
    product = relationship("Product", back_populates="images")

CodePudding user response:

You need to join the urls in the for-loop.

first make an empty array to store the file urls, then in the for loop append to it. Then finally use join to concatenate the strings with commas to give you a string with comma separated items

fileList = []
for file in files:
        try:
            FILEPATH = "./static/product_images/"
            pimage_name = FILEPATH   imghex(file.filename)
            contents = await file.read()
            with open(pimage_name, 'wb') as f:
                f.write(contents)
        except Exception:
            return {"message": "There was an error uploading the file(s)"}
        finally:
            await file.close()
        fileList.append("localhost:8000"   pimage_name[1:])

    file_urls = ",".join(fileList)

  • Related