jowilf / sqlalchemy-file

SQLAlchemy-file is a SQLAlchemy extension for attaching files to SQLAlchemy model and uploading them to various storage such as Local Storage, Amazon S3, Rackspace CloudFiles, Google Storage and others using Apache Libcloud.
https://jowilf.github.io/sqlalchemy-file/
MIT License
82 stars 11 forks source link
attachments azure-storage file-upload libcloud minio-storage python3 s3-storage sqlalchemy sqlmodel

sqlalchemy-file

SQLAlchemy-file is a SQLAlchemy extension for attaching files to SQLAlchemy model and uploading them to various storage such as Local Storage, Amazon S3, Rackspace CloudFiles, Google Storage and others using Apache Libcloud.

Test suite Publish Codecov Package version Supported Python versions

The key features are:


Documentation: https://jowilf.github.io/sqlalchemy-file

Source Code: https://github.com/jowilf/sqlalchemy-file


Requirements

A recent and currently supported version of Python (right now, Python supports versions 3.7 and above).

As SQLAlchemy-file is based on Apache Libcloud and SQLAlchemy, it requires them. They will be automatically installed when you install SQLAlchemy-file.

Installation

PIP

$ pip install sqlalchemy-file

Poetry

$ poetry add sqlalchemy-file

Example

Attaching files to models is as simple as declaring a field on the model itself

import os

from libcloud.storage.drivers.local import LocalStorageDriver
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
from sqlalchemy_file import File, FileField
from sqlalchemy_file.storage import StorageManager

Base = declarative_base()

# Define your model
class Attachment(Base):
    __tablename__ = "attachment"

    id = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(String(50), unique=True)
    content = Column(FileField)

# Configure Storage
os.makedirs("./upload_dir/attachment", 0o777, exist_ok=True)
container = LocalStorageDriver("./upload_dir").get_container("attachment")
StorageManager.add_storage("default", container)

# Save your model
engine = create_engine(
    "sqlite:///example.db", connect_args={"check_same_thread": False}
)
Base.metadata.create_all(engine)

with Session(engine) as session, open("./example.txt", "rb") as local_file:
    # from an opened local file
    session.add(Attachment(name="attachment1", content=local_file))

    # from bytes
    session.add(Attachment(name="attachment2", content=b"Hello world"))

    # from string
    session.add(Attachment(name="attachment3", content="Hello world"))

    # from a File object with custom filename and content_type
    file = File(content="Hello World", filename="hello.txt", content_type="text/plain")
    session.add(Attachment(name="attachment4", content=file))

    # from a File object specifying a content path
    session.add(Attachment(name="attachment5", content=File(content_path="./example.txt")))

    session.commit()

Related projects and inspirations