BaseCRUD model

This commit is contained in:
2023-05-15 21:14:06 +03:00
parent 02b8e86ccf
commit ffbc6bf88b
4 changed files with 105 additions and 51 deletions

21
app/database/db.py Normal file
View File

@@ -0,0 +1,21 @@
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from app.settings import settings
Base = declarative_base()
from sqlalchemy.pool import QueuePool
# Create async engine with connection pooling
engine = create_async_engine(
settings.DATABASE_URL,
echo=True,
poolclass=QueuePool,
pool_size=5,
max_overflow=10,
)
# Create async session factory
async_session = sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False
)

80
app/database/models.py Normal file
View File

@@ -0,0 +1,80 @@
from typing import List
from sqlalchemy import Column, String
from sqlalchemy import update as sqlalchemy_update, delete as sqlalchemy_delete
from sqlalchemy.future import select
from app.database.db import Base, async_session
from uuid import uuid4
from typing_extensions import Self
class BaseCRUD(Base):
__abstract__ = True
id = Column(String, primary_key=True)
def __repr__(self):
return (
f"<{self.__class__.__name__}("
f"id={self.id}, "
f"name={self.name}, "
f")>"
)
@classmethod
async def create(cls, **kwargs) -> Self:
async with async_session() as db:
server = cls(id=str(uuid4()), **kwargs)
db.add(server)
try:
await db.commit()
await db.refresh(server)
except Exception:
await db.rollback()
raise
return server
@classmethod
async def update(cls, id, **kwargs) -> Self:
async with async_session() as db:
query = (
sqlalchemy_update(cls)
.where(cls.id == id)
.values(**kwargs)
.execution_options(synchronize_session="fetch")
)
await db.execute(query)
try:
await db.commit()
except Exception:
await db.rollback()
raise
return await cls.get(id)
@classmethod
async def get(cls, id) -> Self:
async with async_session() as db:
query = select(cls).where(cls.id == id)
servers = await db.execute(query)
(server,) = servers.first()
return server
@classmethod
async def get_all(cls) -> List[Self]:
async with async_session() as db:
query = select(cls)
servers = await db.execute(query)
servers = servers.scalars().all()
return servers
@classmethod
async def delete(cls, id) -> bool:
async with async_session() as db:
query = sqlalchemy_delete(cls).where(cls.id == id)
await db.execute(query)
try:
await db.commit()
except Exception:
await db.rollback()
raise
return True

View File

@@ -1,49 +0,0 @@
from sqlalchemy import future
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from app.settings import settings
Base = declarative_base()
# engine = create_async_engine(settings.DATABASE_URL, echo=True, future=True)
# Session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
# def get_session():
# with Session() as session:
# yield session
class AsyncDatabaseSession:
def __init__(self):
self._session = None
self._engine = None
self._engine = create_async_engine(
settings.DATABASE_URL,
future=True,
echo=True,
)
self._session = sessionmaker(
self._engine, expire_on_commit=False, class_=AsyncSession
)()
def __getattr__(self, name):
return getattr(self._session, name)
# def init(self):
db = AsyncDatabaseSession()
# async def get_session() -> AsyncSession:
# async_session = sessionmaker(
# engine, class_=AsyncSession, expire_on_commit=False
# )
# async with async_session() as session:
# yield session
# # from sqlalchemy import create_engine
# # from sqlalchemy.ext.declarative import declarative_base
# # from sqlalchemy.orm import sessionmaker
# engine = create_engine(settings.DATABASE_URL)
# SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

View File

@@ -9,7 +9,9 @@ from sqlalchemy.ext.asyncio import AsyncEngine
from alembic import context
from app.settings import settings
import users
from app.database import db
# your models to import for migrations processing
from users.models import *
# this is the Alembic Config object, which provides
@@ -27,7 +29,7 @@ config.set_main_option('sqlalchemy.url', settings.DATABASE_URL)
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = [users.models.Base.metadata]
target_metadata = db.Base.metadata
# other values from the config, defined by the needs of env.py,
# can be acquired: