From 93cf7b2d240fc0b35ef4b904a6f3ccfb6da8a979 Mon Sep 17 00:00:00 2001 From: IluaAir Date: Wed, 6 Aug 2025 23:38:17 +0300 Subject: [PATCH] event listens for sqlalchemy --- src/api/v1/users.py | 9 +++------ src/core/database.py | 16 ++++++++++++++-- src/migrations/env.py | 11 +++++++++-- src/repository/users.py | 8 ++++++-- src/services/users.py | 3 +-- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/api/v1/users.py b/src/api/v1/users.py index e39e715..03d0c5d 100644 --- a/src/api/v1/users.py +++ b/src/api/v1/users.py @@ -29,11 +29,8 @@ async def get_user_by_id(db: sessionDep, id: int, _: CurrentOrAdmin): @router.patch("/{id}") async def patch_user( - db: sessionDep, - id: int, - _: CurrentOrAdmin, - user_update: UserUpdate = Body() - ): + db: sessionDep, id: int, _: CurrentOrAdmin, user_update: UserUpdate = Body() +): updated_user = await UserService(db).update_user(id=id, update_data=user_update) return updated_user @@ -41,4 +38,4 @@ async def patch_user( @router.delete("/{id}") async def delete_user(db: sessionDep, id: int, _: AdminUser): await UserService(db).delete_user(id) - return {"message": "User deleted successfully"} \ No newline at end of file + return {"message": "User deleted successfully"} diff --git a/src/core/database.py b/src/core/database.py index 12da284..901bc1a 100644 --- a/src/core/database.py +++ b/src/core/database.py @@ -1,12 +1,24 @@ from datetime import datetime -from sqlalchemy import TIMESTAMP, func +from sqlalchemy import TIMESTAMP, func, event from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from src.core.settings import settings -engine = create_async_engine(settings.db.url, echo=True) +engine = create_async_engine( + settings.db.url, + echo=True +) + + +@event.listens_for(engine.sync_engine, "connect") +def set_sqlite_pragma(dbapi_connection, connection_record): + if "sqlite" in settings.db.url: + cursor = dbapi_connection.cursor() + cursor.execute("PRAGMA foreign_keys=ON") + cursor.close() + async_session_maker = async_sessionmaker(bind=engine, expire_on_commit=False) diff --git a/src/migrations/env.py b/src/migrations/env.py index 2bfab37..695e45d 100644 --- a/src/migrations/env.py +++ b/src/migrations/env.py @@ -1,8 +1,7 @@ from logging.config import fileConfig -from sqlalchemy import engine_from_config +from sqlalchemy import engine_from_config, event from sqlalchemy import pool - from alembic import context from src.core.database import Base @@ -67,6 +66,14 @@ def run_migrations_online() -> None: poolclass=pool.NullPool, ) + # Enable foreign keys for SQLite in migrations + @event.listens_for(connectable, "connect") + def set_sqlite_pragma(dbapi_connection, connection_record): + print("⚙️ Enabling PRAGMA foreign_keys=ON for Alembic") + cursor = dbapi_connection.cursor() + cursor.execute("PRAGMA foreign_keys=ON") + cursor.close() + with connectable.connect() as connection: context.configure(connection=connection, target_metadata=target_metadata) diff --git a/src/repository/users.py b/src/repository/users.py index def44c9..4f11a90 100644 --- a/src/repository/users.py +++ b/src/repository/users.py @@ -1,6 +1,5 @@ from sqlalchemy import delete, select, update -from schemas.users import User from src.models import UsersORM from src.repository.base import BaseRepo @@ -18,7 +17,12 @@ class UsersRepo(BaseRepo): await self.session.execute(delete(self.model).where(self.model.id == id)) async def update_one(self, id: int, data: dict) -> UsersORM: - stmt = update(self.model).where(self.model.id == id).values(data.model_dump(exclude_unset=True)).returning(self.model) + stmt = ( + update(self.model) + .where(self.model.id == id) + .values(data.model_dump(exclude_unset=True)) + .returning(self.model) + ) result = await self.session.execute(stmt) model = result.scalar_one() return model diff --git a/src/services/users.py b/src/services/users.py index 3bb5983..5f921fb 100644 --- a/src/services/users.py +++ b/src/services/users.py @@ -30,10 +30,9 @@ class UserService(BaseService): async def delete_user(self, id: int) -> None: await self.session.user.delete_one(id=id) await self.session.commit() - + async def update_user(self, id: int, update_data: UserUpdate) -> User: await self.get_user_by_filter_or_raise(id=id) user = await self.session.user.update_one(id=id, data=update_data) await self.session.commit() return User.model_validate(user) -