Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Где Ormar берет список всех моделей?
Ormar — это асинхронный Python ORM, построенный на основе SQLAlchemy Core и databases. Список всех моделей хранится и управляется несколькими ключевыми местами:
1. Реестр моделей в базовом классе
Когда вы создаёте модель, наследуя от ormar.Model, она автоматически регистрируется в глобальном реестре:
import ormar
import databases
import sqlalchemy
database = databases.Database("sqlite:///database.db")
metadata = sqlalchemy.MetaData()
basemeta = ormar.ModelMetaclass
class User(ormar.Model):
class Meta:
tablename = "users"
metadata = metadata
database = database
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
Внутри Ormar используется метакласс ModelMetaclass, который при создании класса добавляет его в реестр.
2. Доступ к глобальному реестру
Основной реестр моделей находится в ormar.signals.QueryFields.registry или ormar.QuerySet.registry. Его можно получить несколькими способами:
# Способ 1: через класс Model
from ormar import Model
all_models = Model.__subclasses__()
# Способ 2: через метаданные
all_tables = metadata.tables
# Способ 3: через регистр SQLAlchemy
all_models = [mapper.class_ for mapper in sqlalchemy.inspect(User).registry.mappers]
3. Метаклассовая магия
Когда класс наследует от ormar.Model, срабатывает __init_subclass__() (или обработка метаклассом), которая:
- Извлекает Meta-информацию (tablename, database, metadata)
- Регистрирует модель в глобальном реестре
- Создаёт SQLAlchemy Table с колонками
- Добавляет методы для CRUD операций
class ModelMetaclass(type):
def __new__(mcs, name, bases, namespace, **kwargs):
# Регистрация модели
# Создание таблицы
# Установка методов
return super().__new__(mcs, name, bases, namespace)
4. Получение всех моделей в Ormar
Наиболее надежный способ получить список всех моделей:
import ormar
# Получить все подклассы Model
all_models = ormar.Model.__subclasses__()
# Если нужны только "конкретные" модели (не абстрактные)
conrete_models = [
model for model in all_models
if hasattr(model, __tablename__)
]
# Или через словарь
from ormar.signals import QueryFields
model_registry = QueryFields.get_all_models() # если доступно
5. Практический пример
import ormar
def get_all_models():
"""Получить список всех Ormar моделей."""
return ormar.Model.__subclasses__()
def create_all_tables():
"""Создать все таблицы."""
models = get_all_models()
metadata.create_all(engine)
# Использование
all_models = get_all_models()
for model in all_models:
print(f"Модель: {model.__name__}, таблица: {model.__tablename__}")
6. Важные детали
- Порядок импорта: все модели должны быть импортированы ДО использования реестра
- Глобальный реестр: Ormar использует одну глобальную метаду SQLAlchemy
- Метаклассы: регистрация работает через Python метаклассы, что позволяет это делать автоматически
В современных версиях Ormar реестр модели доступен напрямую через SQLAlchemy registry, что обеспечивает чистое разделение ответственности между ORM и ядром SQLAlchemy.