Loading repository data…
Loading repository data…
LuisLuii / repository
Generate CRUD methods in FastApi from an SQLAlchemy schema
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.

I believe that many people who work with FastApi to build RESTful CRUD services end up wasting time writing repitive boilerplate code.
FastAPI Quick CRUD can generate CRUD methods in FastApi from an SQLAlchemy schema:
FastAPI Quick CRUDis developed based on SQLAlchemy 1.4.23 version and supports sync and async.

Support SQLAlchemy 1.4 - Allows you build a fully asynchronous or synchronous python service
Full SQLAlchemy DBAPI Support - Support different SQL for SQLAlchemy
Support Pagination - Get many API support order by offset limit field in API
Rich FastAPI CRUD router generation - Many operations of CRUD are implemented to complete the development and coverage of all aspects of basic CRUD.
CRUD route automatically generated - Support Declarative class definitions and Imperative table
Flexible API request - UPDATE ONE/MANY FIND ONE/MANY PATCH ONE/MANY DELETE ONE/MANY supports Path Parameters (primary key) and Query Parameters as a command to the resource to filter and limit the scope of the scope of data in request.
SQL Relationship - FIND ONE/MANY supports Path get data with relationship
xxx/{primary key} for tables without a primary key;
UPDATE ONEFIND ONEPATCH ONEDELETE ONEI try to update the version dependencies as soon as possible to ensure that the core dependencies of this project have the highest version possible.
fastapi<=0.68.2
pydantic<=1.8.2
SQLAlchemy<=1.4.30
starlette==0.14.2
pip install fastapi-quickcrud
I suggest the following library if you try to connect to PostgreSQL
pip install psycopg2
pip install asyncpg
run and go to http://127.0.0.1:port/docs and see the auto-generated API
from fastapi import FastAPI
from sqlalchemy import Column, Integer, \
String, Table, ForeignKey, orm
from fastapi_quickcrud import crud_router_builder
Base = orm.declarative_base()
class User(Base):
__tablename__ = 'test_users'
id = Column(Integer, primary_key=True, autoincrement=True, unique=True)
name = Column(String, nullable=False)
email = Column(String, nullable=False)
friend = Table(
'test_friend', Base.metadata,
Column('id', ForeignKey('test_users.id', ondelete='CASCADE', onupdate='CASCADE'), nullable=False),
Column('friend_name', String, nullable=False)
)
crud_route_1 = crud_router_builder(db_model=User,
prefix="/user",
tags=["User"],
async_mode=True
)
crud_route_2 = crud_router_builder(db_model=friend,
prefix="/friend",
tags=["friend"],
async_mode=True
)
app = FastAPI()
app.include_router(crud_route_1)
app.include_router(crud_route_2)
from fastapi import FastAPI
from fastapi_quickcrud import crud_router_builder
from sqlalchemy import *
from sqlalchemy.orm import *
from fastapi_quickcrud.crud_router import generic_sql_crud_router_builder
Base = declarative_base()
class Account(Base):
__tablename__ = "account"
id = Column(Integer, primary_key=True, autoincrement=True)
blog_post = relationship("BlogPost", back_populates="account")
class BlogPost(Base):
__tablename__ = "blog_post"
id = Column(Integer, primary_key=True, autoincrement=True)
account_id = Column(Integer, ForeignKey("account.id"), nullable=False)
account = relationship("Account", back_populates="blog_post")
blog_comment = relationship("BlogComment", back_populates="blog_post")
class BlogComment(Base):
__tablename__ = "blog_comment"
id = Column(Integer, primary_key=True, autoincrement=True)
blog_id = Column(Integer, ForeignKey("blog_post.id"), nullable=False)
blog_post = relationship("BlogPost", back_populates="blog_comment")
crud_route_parent = crud_router_builder(
db_model=Account,
prefix="/account",
tags=["account"],
foreign_include=[BlogComment, BlogPost]
)
crud_route_child1 = generic_sql_crud_router_builder(
db_model=BlogPost,
prefix="/blog_post",
tags=["blog_post"],
foreign_include=[BlogComment]
)
crud_route_child2 = generic_sql_crud_router_builder(
db_model=BlogComment,
prefix="/blog_comment",
tags=["blog_comment"]
)
app = FastAPI()
[app.include_router(i) for i in [crud_route_parent, crud_route_child1, crud_route_child2]]
import uvicorn
from fastapi import FastAPI, Depends
from fastapi_quickcrud import CrudMethods
from fastapi_quickcrud import sqlalchemy_to_pydantic
from fastapi_quickcrud.misc.memory_sql import sync_memory_db
from sqlalchemy import CHAR, Column, Integer
from sqlalchemy.ext.declarative import declarative_base
app = FastAPI()
Base = declarative_base()
metadata = Base.metadata
class Child(Base):
__tablename__ = 'right'
id = Column(Integer, primary_key=True)
name = Column(CHAR, nullable=True)
friend_model_set = sqlalchemy_to_pydantic(db_model=Child,
crud_methods=[
CrudMethods.FIND_MANY,
CrudMethods.UPSERT_MANY,
CrudMethods.UPDATE_MANY,
CrudMethods.DELETE_MANY,
CrudMethods.CREATE_ONE,
CrudMethods.PATCH_MANY,
],
exclude_columns=[])
post_model = friend_model_set.POST[CrudMethods.CREATE_ONE]
sync_memory_db.create_memory_table(Child)
@app.post("/hello",
status_code=201,
tags=["Child"],
response_model=post_model.responseModel,
dependencies=[])
async def my_api(
query: post_model.requestBodyModel = Depends(post_model.requestBodyModel),
session=Depends(sync_memory_db.get_memory_db_session)
):
db_item = Child(**query.__dict__)
session.add(db_item)
session.commit()
session.refresh(db_item)
return db_item.__dict__
uvicorn.run(app, host="0.0.0.0", port=8000, debug=False)
crud_router_builder args
db_session [Optional] execute session generator
from sqlalchemy.orm import sessionmaker
def get_transaction_session():
try:
db = sessionmaker(...)
yield db
except Exception as e:
db.rollback()
raise e
finally:
db.close()
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.asyncio import AsyncSession
async_session = sessionmaker(autocommit=False,
autoflush=False,
bind=engine,
class_=AsyncSession)
async def get_transaction_session() -> AsyncSession:
async with async_session() as session:
async with session.begin():
yield session
db_model [Require] SQLALchemy Declarative Base Class or Table
Note: There are some constraint in the SQLALchemy Schema
async_mode [Optional (auto set by db_session)] bool: if your db session is async
Note: require async session generator if True
autocommit [Optional (default True)] bool: if you don't need to commit by your self
Note: require handle the commit in your async session generator if False
dependencies [Optional]: API dependency injection of fastapi
Note: Get the example usage in
./example
crud_methods: CrudMethods
- CrudMethods.FIND_ONE
- CrudMethods.FIND_MANY
- CrudMethods.UPDATE_ONE
- CrudMethods.UPDATE_MANY
- CrudMethods.PATCH_ONE
- CrudMethods.PATCH_MANY
- CrudMethods.UPSERT_ONE (only support postgresql yet)
- CrudMethods.UPSERT_MANY (only support postgresql yet)
- CrudMethods.CREATE_ONE
- CrudMethods.CREATE_MANY
- CrudMethods.DELETE_ONE
- CrudMethods.DELETE_MANY
- CrudMethods.POST_REDIRECT_GET
exclude_columns: list
set the columns that not to be operated but the columns should nullable or set the default value)
foreign_include: `list[declarative_base(