Py-Models-Parser — текстовый парсер Python моделей и определений таблиц, который извлекает структурную информацию из различных ORM-фреймворков без необходимости импортировать исходный код.
Парсер использует PEG (Parsing Expression Grammar) через библиотеку parsimonious для анализа текста кода как строк.
- SQLAlchemy ORM
- Gino ORM
- Tortoise ORM
- Encode ORM
- Django ORM Models
- Pydantic
- Python Enums
- Pony ORM
- Piccolo ORM
- Pydal Tables (Web2Py)
- Python Dataclasses
- Чистые Python классы
- OpenAPI 3.0/Swagger specifications
py-models-parser/
├── py_models_parser/ # Основной пакет
│ ├── __init__.py # Публичный API
│ ├── core.py # Основная логика парсинга
│ ├── grammar.py # PEG грамматика
│ ├── visitor.py # Visitor для преобразования AST
│ ├── types.py # Определения типов и триггеры
│ ├── utils.py # Утилиты
│ ├── cli.py # CLI интерфейс
│ └── parsers/
│ ├── pydal.py # Специализированный парсер для Pydal
│ └── openapi.py # Парсер OpenAPI/Swagger спецификаций
├── tests/ # Тесты
│ ├── test_*.py # Тесты для каждого типа моделей
│ └── data/ # Тестовые данные
├── tox.ini # Конфигурация tox для мультиверсионного тестирования
└── pyproject.toml # Конфигурация Poetry
Экспортирует функции:
parse(models: str)— парсинг строки с Python моделямиparse_from_file(file_path)— парсинг Python моделей из файлаdump_result(output, file_path)— сохранение результатов в JSONparse_openapi(content: str)— парсинг OpenAPI спецификации из строкиparse_openapi_file(file_path)— парсинг OpenAPI спецификации из файла
Главный модуль с логикой парсинга:
| Функция | Назначение |
|---|---|
parse() |
Главная функция парсинга |
parse_from_file() |
Парсинг из файла |
pre_processing() |
Удаление импортов, комментариев, декораторов |
get_models_type() |
Определение типа модели |
sqlalchemy_type_identify() |
Различие SQLAlchemy ORM и Core |
format_ouput() |
Постобработка результатов |
process_models_attr() |
Разрешение ссылок на другие модели |
clear_parents() |
Удаление служебной информации |
PEG-грамматика для парсинга:
expr → (class/if_else/call_result/...)* - корневое выражение
class → class_def attr_def* funct_def* - определение класса
class_def → class_name args? ":"* - сигнатура класса
attr_def → id type? ("=" right_part)* - атрибут
type → ":" (id args_in_brackets / id) - аннотация типа
args → "(" (list/call_result/...)* ")" - аргументы
Класс Visitor(NodeVisitor) для преобразования AST в структуры данных:
| Метод | Назначение |
|---|---|
visit_class_name() |
Извлечение названия класса |
visit_class_def() |
Обработка определения класса |
visit_attr_def() |
Обработка атрибута |
visit_right_part() |
Анализ правой части присваивания |
visit_type() |
Парсинг аннотаций типов |
extract_orm_attr() |
Извлечение параметров ORM |
_process_attr() |
Классификация атрибутов |
Конфигурация для распознавания типов моделей:
orm_triggers = ["Column", "Field", "relationship"]
pony_orm_fields = ["Required", "Set", "Optional", "PrimaryKey"]
ormar_and_piccollo_types = ["Integer", "String", "Text", ...]Интерфейс командной строки:
pmp path_to_models.py [-d output.json]Входной Python-код
│
▼
┌─────────────────────┐
│ pre_processing() │ Удаление импортов, комментариев
│ get_models_type() │ Определение типа модели
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ grammar.parse() │ PEG парсинг → AST
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ Visitor.visit() │ Обход AST
│ extract_orm_attr() │ Распознавание ORM-параметров
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ format_ouput() │ Постобработка
│ process_models_attr │
│ clear_parents() │
└─────────┬───────────┘
│
▼
Структурированный JSON
{
"name": str, # Имя класса/модели
"parents": [str], # Родительские классы
"attrs": [
{
"name": str, # Имя атрибута
"type": str, # Тип данных
"default": str, # Значение по умолчанию
"properties": { # Метаданные
"primary_key": bool,
"nullable": bool,
"foreign_key": str,
...
}
}
],
"properties": { # Свойства модели
"table_name": str,
"table_args": str,
...
}
}Runtime:
parsimonious^0.10.0 — PEG парсер для Python моделейpyyaml^6.0 — парсер YAML для OpenAPI спецификаций
Development:
pytest^7.4tox— мультиверсионное тестирование
Python: 3.9, 3.10, 3.11, 3.12, 3.13
# Парсинг Python моделей из строки
from py_models_parser import parse
result = parse(models_string)
# Парсинг Python моделей из файла
from py_models_parser import parse_from_file
result = parse_from_file("path/to/models.py")
# Парсинг OpenAPI спецификации
from py_models_parser import parse_openapi, parse_openapi_file
result = parse_openapi(openapi_yaml_string)
result = parse_openapi_file("path/to/openapi.yaml")# CLI
pmp models.py -d output.jsonДля добавления поддержки нового ORM:
- Добавить триггеры в
types.py - Расширить грамматику в
grammar.py(при необходимости) - Добавить методы в
visitor.pyдля специфики ORM - Создать специализированный парсер в
parsers/(опционально)