Добавлены базы и роуты для Серверов и Баз Данных
This commit is contained in:
9
core/__init__.py
Normal file
9
core/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
__all__ = (
|
||||
"settings",
|
||||
"db_helper",
|
||||
"Base"
|
||||
)
|
||||
from .settings import settings
|
||||
from .db_helper import db_helper
|
||||
from .base import Base
|
||||
from .models import *
|
6
core/base.py
Normal file
6
core/base.py
Normal file
@ -0,0 +1,6 @@
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
from sqlalchemy import MetaData
|
||||
from core.settings import settings
|
||||
class Base(DeclarativeBase):
|
||||
__abstract__ = True
|
||||
metadata = MetaData(naming_convention=settings.database.convention)
|
0
core/crud/__init__.py
Normal file
0
core/crud/__init__.py
Normal file
53
core/crud/databases.py
Normal file
53
core/crud/databases.py
Normal file
@ -0,0 +1,53 @@
|
||||
from ..models import Database
|
||||
from ..schemas import DatabaseBase, DatabaseSchema
|
||||
from sqlalchemy import select, delete
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from typing import Sequence, Optional, List
|
||||
async def get_all(
|
||||
session: AsyncSession
|
||||
) -> Sequence[DatabaseSchema]:
|
||||
stmt = select(Database).order_by(Database.id)
|
||||
result = await session.scalars(stmt)
|
||||
return result.all()
|
||||
|
||||
async def get(
|
||||
session: AsyncSession,
|
||||
id: int
|
||||
) -> DatabaseSchema:
|
||||
db_login = await session.get(Database,id)
|
||||
if db_login is None:
|
||||
return None
|
||||
return db_login
|
||||
|
||||
async def create(
|
||||
session:AsyncSession,
|
||||
model: DatabaseBase
|
||||
) -> DatabaseSchema:
|
||||
login = Database(**model.model_dump())
|
||||
session.add(login)
|
||||
await session.commit()
|
||||
return login
|
||||
|
||||
async def delete(
|
||||
session: AsyncSession,
|
||||
id: int
|
||||
):
|
||||
db_login = await session.get(Database,id)
|
||||
if db_login is None:
|
||||
return None
|
||||
stmt = delete(Database).filter(Database.id == id)
|
||||
await session.execute(stmt)
|
||||
await session.commit()
|
||||
|
||||
async def update(
|
||||
session:AsyncSession,
|
||||
id: int,
|
||||
model: DatabaseBase
|
||||
) -> DatabaseSchema:
|
||||
db_login = await session.get(Database,id)
|
||||
if db_login is None:
|
||||
return None
|
||||
for var, value in vars(model).items():
|
||||
setattr(db_login, var, value) if value else None
|
||||
await session.commit()
|
||||
return db_login
|
53
core/crud/servers.py
Normal file
53
core/crud/servers.py
Normal file
@ -0,0 +1,53 @@
|
||||
from ..models import Server
|
||||
from ..schemas import ServerBase, ServerSchema
|
||||
from sqlalchemy import select, delete
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from typing import Sequence, Optional, List
|
||||
async def get_all(
|
||||
session: AsyncSession
|
||||
) -> Sequence[ServerSchema]:
|
||||
stmt = select(Server).order_by(Server.id)
|
||||
result = await session.scalars(stmt)
|
||||
return result.all()
|
||||
|
||||
async def get(
|
||||
session: AsyncSession,
|
||||
id: int
|
||||
) -> ServerSchema:
|
||||
db_login = await session.get(Server,id)
|
||||
if db_login is None:
|
||||
return None
|
||||
return db_login
|
||||
|
||||
async def create(
|
||||
session:AsyncSession,
|
||||
model: ServerBase
|
||||
) -> ServerSchema:
|
||||
login = Server(**model.model_dump())
|
||||
session.add(login)
|
||||
await session.commit()
|
||||
return login
|
||||
|
||||
async def delete(
|
||||
session: AsyncSession,
|
||||
id: int
|
||||
):
|
||||
db_login = await session.get(Server,id)
|
||||
if db_login is None:
|
||||
return None
|
||||
stmt = delete(Server).filter(Server.id == id)
|
||||
await session.execute(stmt)
|
||||
await session.commit()
|
||||
|
||||
async def update(
|
||||
session:AsyncSession,
|
||||
id: int,
|
||||
model: ServerBase
|
||||
) -> ServerSchema:
|
||||
db_login = await session.get(Server,id)
|
||||
if db_login is None:
|
||||
return None
|
||||
for var, value in vars(model).items():
|
||||
setattr(db_login, var, value) if value else None
|
||||
await session.commit()
|
||||
return db_login
|
46
core/db_helper.py
Normal file
46
core/db_helper.py
Normal file
@ -0,0 +1,46 @@
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine, async_sessionmaker, AsyncSession
|
||||
from typing import AsyncGenerator
|
||||
from core.settings import settings
|
||||
class DatabaseHelper:
|
||||
def __init__(
|
||||
self,
|
||||
url: str,
|
||||
echo:bool=False,
|
||||
echo_pool:bool=False,
|
||||
pool_size: int = 5,
|
||||
max_overflow: int =10,
|
||||
) -> None:
|
||||
try:
|
||||
self.engine: AsyncEngine = create_async_engine(
|
||||
url=url,
|
||||
echo=echo,
|
||||
echo_pool=echo_pool,
|
||||
pool_size=pool_size,
|
||||
max_overflow = max_overflow
|
||||
)
|
||||
except TypeError:
|
||||
# The pool_size argument won't work for the default SQLite setup in SQLAlchemy 0.7, try without
|
||||
self.engine: AsyncEngine = create_async_engine(url=url)
|
||||
|
||||
self.session_factory: async_sessionmaker[AsyncSession] = async_sessionmaker(
|
||||
bind= self.engine,
|
||||
autoflush=False,
|
||||
autocommit=False,
|
||||
expire_on_commit=False
|
||||
)
|
||||
|
||||
async def dispose(self) -> None:
|
||||
await self.engine.dispose()
|
||||
|
||||
async def session_getter(self) -> AsyncGenerator[AsyncSession,None]:
|
||||
async with self.session_factory() as session:
|
||||
yield session
|
||||
|
||||
db_helper = DatabaseHelper(
|
||||
url = settings.database.url,
|
||||
echo = settings.database.echo,
|
||||
echo_pool = settings.database.echo_pool,
|
||||
pool_size = settings.database.pool_size,
|
||||
max_overflow = settings.database.max_overflow,
|
||||
|
||||
)
|
20
core/models.py
Normal file
20
core/models.py
Normal file
@ -0,0 +1,20 @@
|
||||
from .base import Base
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy import String, Integer, Boolean, ForeignKey, DateTime
|
||||
from datetime import date, datetime
|
||||
class Server(Base):
|
||||
__tablename__ = "easy_servers"
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name:Mapped[str] = mapped_column(String(255), nullable=False, unique=True)
|
||||
description: Mapped[str | None] = mapped_column(String(1000), nullable=True)
|
||||
url: Mapped[str] = mapped_column(String(1000), nullable=False, unique=False)
|
||||
|
||||
|
||||
class Database(Base):
|
||||
__tablename__ = "easy_databases"
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name:Mapped[str] = mapped_column(String(255), nullable=False, unique=True)
|
||||
description: Mapped[str | None] = mapped_column(String(1000), nullable=True)
|
||||
date_created: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, default= func.now())
|
||||
server_id: Mapped[int] = mapped_column(Integer, ForeignKey("easy_servers.id"))
|
10
core/router.py
Normal file
10
core/router.py
Normal file
@ -0,0 +1,10 @@
|
||||
from fastapi import APIRouter
|
||||
from .routers.servers import router as server_router
|
||||
router = APIRouter(
|
||||
tags=["Core"],
|
||||
prefix="/core",
|
||||
)
|
||||
|
||||
router.include_router(
|
||||
router=server_router,
|
||||
)
|
0
core/routers/__init__.py
Normal file
0
core/routers/__init__.py
Normal file
40
core/routers/servers.py
Normal file
40
core/routers/servers.py
Normal file
@ -0,0 +1,40 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from ..crud.servers import get, get_all,delete,update, create
|
||||
from typing import Annotated, Sequence
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from ..db_helper import db_helper
|
||||
from ..schemas import ServerBase, ServerSchema
|
||||
router = APIRouter( tags=["Server"], prefix="/server")
|
||||
|
||||
@router.get("/", response_model=Sequence[ServerSchema])
|
||||
async def get_all_server(session: Annotated[AsyncSession, Depends(db_helper.session_getter)]):
|
||||
return await get_all(session)
|
||||
|
||||
|
||||
@router.get("/{id}", response_model=ServerSchema)
|
||||
async def get_server(session: Annotated[AsyncSession, Depends(db_helper.session_getter)],id:int):
|
||||
return await get(session,id)
|
||||
|
||||
@router.post("/", response_model=ServerSchema)
|
||||
async def create_server(
|
||||
session: Annotated[AsyncSession, Depends(db_helper.session_getter)],
|
||||
model: ServerBase
|
||||
):
|
||||
login = await create(
|
||||
session=session,
|
||||
model=model
|
||||
)
|
||||
return login
|
||||
|
||||
@router.patch("/{id}", response_model=ServerSchema)
|
||||
async def update_server(
|
||||
session: Annotated[AsyncSession, Depends(db_helper.session_getter)],
|
||||
id: int,
|
||||
model: ServerBase
|
||||
):
|
||||
login = await update(
|
||||
session=session,
|
||||
id=id,
|
||||
model=model
|
||||
)
|
||||
return login
|
19
core/schemas.py
Normal file
19
core/schemas.py
Normal file
@ -0,0 +1,19 @@
|
||||
from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
|
||||
class ServerBase(BaseModel):
|
||||
name:str
|
||||
description: str | None
|
||||
url: str
|
||||
|
||||
class ServerSchema(ServerBase):
|
||||
id: int
|
||||
|
||||
class DatabaseBase(BaseModel):
|
||||
name:str
|
||||
description: str | None
|
||||
date_created: datetime | None
|
||||
server_id: int
|
||||
|
||||
class DatabaseSchema(DatabaseBase):
|
||||
id: int
|
36
core/settings.py
Normal file
36
core/settings.py
Normal file
@ -0,0 +1,36 @@
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
from pydantic import BaseModel
|
||||
|
||||
class UvicornSettings(BaseModel):
|
||||
host: str = "0.0.0.0"
|
||||
port: int = 8000
|
||||
reload: bool = True
|
||||
|
||||
class DatabaseSettings(BaseModel):
|
||||
url: str
|
||||
echo:bool=False
|
||||
echo_pool:bool=False
|
||||
pool_size: int = 50
|
||||
max_overflow: int =10
|
||||
convention:dict = {
|
||||
"ix": "ix_%(column_0_label)s",
|
||||
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
||||
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
||||
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
||||
"pk": "pk_%(table_name)s",
|
||||
}
|
||||
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(
|
||||
env_file=".env",
|
||||
case_sensitive=False,
|
||||
env_nested_delimiter="__",
|
||||
env_prefix="APP_CONFIG__"
|
||||
)
|
||||
database: DatabaseSettings
|
||||
uvicorn: UvicornSettings = UvicornSettings()
|
||||
|
||||
|
||||
|
||||
settings = Settings()
|
||||
print(settings.database.url)
|
Reference in New Issue
Block a user