← Назад к вопросам

Где Ormar берет список всех моделей?

3.0 Senior🔥 51 комментариев
#FastAPI и Flask

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Где 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.

Где Ormar берет список всех моделей? | PrepBro