Skip to content

Conversation

@Czertilla
Copy link

📌 Основные изменения

✅ Перевод проекта на uv вместо poetry

  • Удалён poetry.lock от Poetry и добавлен аналог от uv uv.lock
  • pyproject.toml переписан под uv
  • Добавлен requirements.txt для возможности простой сборки

🧠 Рефактор моделей под SQLAlchemy 2.0

  • Использование декларативного стиля SQLAlchemy 2.0 (Annotated Declarative Table Forms)
  • Модуль моделей преобразован в полноценный пакет с __init__.py
  • Упрощён и структурирован импорт моделей

🗃️ Новый пакет database

  • Новый модуль database, инкапсулирующий взаимодействие с базами данных

  • Подпакет database.sqlalchemy содержит:

    • Базовую модель и репозиторий efe0321
    • Набор TypeDecorator-ов вынесен в отдельный модуль 91c0a5f
    • Миксины (например, TimestampMixin (1a4d4a5), IDRepositoryMixin (e0502f9))
    • Обёртки для sessionmaker, engine и пр. b379135
    • Прокси класс RepositoryProxy для обратной совместимости f51e890

🧩 Рефакторинг репозиториев

  • Использование нового SQLAlchemy query builder API (select(), update(), insert() и пр.)
  • Удаление использования контекстного менеджера внутри репозиториев
  • Репозитории теперь принимают сущность класса Session как аргумент конструктора
  • Добавлен прокси-класс в AppDatabase, поддерживающий старую логику и обеспечивающий плавный переход cdc8277
  • Полная поддержка транзакций и внешнего управления сессиями
  • Улучшено покрытие тестами и читаемость

⚙️ Обратная совместимость

  • Поддержана обратная совместимость через прокси-класс

🔍 Контекст

Этот рефактор направлен на упрощение архитектуры и улучшение гибкости системы управления базой данных, а также соответствие современным практикам SQLAlchemy 2.0. Он создаёт устойчивую основу для поддержки различных СУБД и более чистого, модульного кода.

uv is a more convenient and powerful tool than poetry, which allows you to install dependencies and many other useful functions more efficiently and faster. This will be especially important when using docker, as it will help speed up the process of building an image on the dependency installation layer and avoid creating venvs inside the container as unnecessary.

edit pyproject.toml: - change the general syntax under uv - add "uv" to dependencies - add section with "uv" settings - add "uvicorn" to dependencies - edit Makefile: - add instructions related to uv  - "venv" for creating a virtual environment - "install" for installing dependencies  - "freeze" for fixing dependencies in "requirements.txt " - delete "poetry.lock" - generate "requirements.txt " using uv for commit purposes for further integration into docker
in earlier versions of sqlalchemy, engines were frequently created to connect to the database (each time a session was created) there were no exceptions, but in more modern versions, the approach to this policy has been tightened.

- webapp.models::create_session_maker now accepts the Engine object instead of the url of the target database - webapp.repository::DbContextManager the engine field has been added, which will be initialized at the first session creation call in order to resolve a conflict of interest with lazy loading of the Flask application configuration - dispose when the Context is closed
The database package encapsulates the basic logic of working with
databases and contains subpackages that implement more specific logic
related to libraries of the same name, such as sqlalchemy.

The type_decorator module is based on part of the code of the
old models module, and completely transfers the IntEnum and JSONArray
classes from there for further use in type_annotation_map.
Move the Status enum-type to a separate module for reuse in
any part of the project.

Meets SOLID and the principle of extensibility: it is possible to
further add new Enums up to the expansion to the package.
The core module encapsulates a basic model that defines meta-settings
for all models used in the project, and a basic repository containing
basic crud methods for better compliance with the principles of
SOLID and DRY.

It is possible to add abstract classes for repositories, generics,
and docstrings to improve the developer experience.
The IDMixin and TimestampMixin classes can be used when creating models
to automatically add the appropriate columns with the necessary
properties. This approach improves compliance with the DRY principle.

It is allowed to expand the module with new classes up to
transformation into a package.
The IDRepositoryMixin class allows you to extend the SQLAlchemy class
based by crud-methods that require id field of model by inheritance
this mixin.

This ensures principles DRY and Interface Segregation (SOLID)
The create_session_maker function is taken from the old models module
and placed in a separate module of the database.sqlalchemy package in
order to maintain modularity, extensibility and customizability.
__init__ module will provide package visibility for some libraries
and the ability to directly import individual elements of package
modules directly from the package itself
This module contains two classes:
- DbContext
- DbContext Manager
for creating a database context and providing transaction mechanics:
- Commit
- Rollback

The main logic of these classes is taken from the old repositories module.
Introduce `RepositoryProxy` in `webapp/database/sqlalchemy/proxy.py`
to bridge modern repository classes (that require a SQLAlchemy
`Session`) with legacy architecture expecting repositories,
that managing context.

This proxy class wraps method calls of a given repository in a
transaction context using `DbContextManager`, allowing seamless
backward-compatible use while supporting updated repositories
written with proper transaction control in mind.

Main benefits:
- Backward compatibility with `AppDatabase` interface
- Transparent session handling per method call
- Enables usage of real transactions in modern code
- Supports gradual migration away from legacy repository patterns

Example usage:
```python
groups: GroupRepository = RepositoryProxy(GroupRepository, context_manager)
```

While this is effectively a workaround, it allows integration of
improved repository implementations into the existing architecture
without disruptive rewrites.
This module contains all the imports and aliases needed to pull the
necessary objects and classes into the namespace of this package
This module contains all the imports and aliases needed to pull the
necessary objects and classes into the namespace of this package
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date.
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date.
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date.
Updating the model to the new sqlalchemy 2.0 syntax will ensure a more
 lightweight and readable code, and the architecture is up-to-date.
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
Czertilla and others added 12 commits May 30, 2025 15:26
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
To align with the new SQLAlchemy repository infrastructure based on
direct `Session` injection. The repository no longer depends on a
context manager that dynamically creates engines and sessions, removing
inverted dependency control and improving performance.

Key improvements:
- Injects `Session` directly via constructor
- Enables real transaction management (incl. multi-crud rollback support)
- Improves testability and composability
- Avoids redundant session/engine initialization per request

This update unlocks the ability to group multiple DB operations into a
single transaction scope, rather than managing a session per repository
method.

Also improves code reuse and reduces duplication by relying on common
base repository behaviors.

Example:
```python
with Session() as session:
    repo = Final Seed Repository(session)
    repo.begin_final_test(group_id)
    session.commit()
```

Also you can include repository initialisation in __enter__
thundermethod of context manager to improve the dev experience, as well
as add initialization of multiple repositories for inter-repository
crud operations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant