GitPedia

Omymodels

O!My Models (omymodels) is a library to generate Pydantic, Dataclasses, GinoORM Models, SqlAlchemy ORM, SqlAlchemy Core Table, Models from SQL DDL. And convert one models to another.

From xnuinside·Updated April 23, 2026·View on GitHub·

**[Interactive Demo](https://xnuinside.github.io/omymodels/)** | **[Documentation](https://github.com/xnuinside/omymodels#how-to-use)** | **[PyPI](https://pypi.org/project/omymodels/)** The project is written primarily in Python, distributed under the MIT License license, first published in 2021. Key topics include: async, code-generation, converter, dataclasses, ddl.

Latest release: 1.0.01.0.0 - Refactoring, Pydantic v2, Pydal, OpenAPI 3, SQLAlchemy 2.0 and more
January 18, 2026View Changelog →

O! My Models

badge1 badge2 badge3 workflow

Interactive Demo | Documentation | PyPI

Try in Web-UI

Try the online O!MyModels converter or simply use it online: https://archon-omymodels-online.hf.space/ (A big thanks for that goes to https://github.com/archongum)

Examples

You can find usage examples in the example/ folder on GitHub: https://github.com/xnuinside/omymodels/tree/main/example

About library

O! My Models (omymodels) is a library that allow you to generate different ORM & pure Python models from SQL DDL or convert one models type to another (exclude SQLAlchemy Table, it does not supported yet by py-models-parser).

Supported Models:

How to install

bash
pip install omymodels

How to use

From Python code

Create Models from DDL

By default method create_models generates GinoORM models. Use the argument models_type to specify output format:

  • 'pydantic' - Pydantic v1 models (uses Optional[X])
  • 'pydantic_v2' - Pydantic v2 models (uses X | None syntax, dict | list for JSON)
  • 'sqlalchemy' - SQLAlchemy ORM models
  • 'sqlalchemy_core' - SQLAlchemy Core Tables
  • 'dataclass' - Python Dataclasses
  • 'sqlmodel' - SQLModel models
  • 'openapi3' - OpenAPI 3 (Swagger) schema definitions

A lot of examples in tests/ - https://github.com/xnuinside/omymodels/tree/main/tests.

Pydantic v1 example

python
from omymodels import create_models ddl = """ CREATE table user_history ( runid decimal(21) null ,job_id decimal(21) null ,id varchar(100) not null ,user varchar(100) not null ,status varchar(10) not null ,event_time timestamp not null default now() ,comment varchar(1000) not null default 'none' ) ; """ result = create_models(ddl, models_type='pydantic')['code'] # output: import datetime from typing import Optional from pydantic import BaseModel class UserHistory(BaseModel): runid: Optional[int] job_id: Optional[int] id: str user: str status: str event_time: datetime.datetime comment: str

Pydantic v2 example

python
from omymodels import create_models ddl = """ CREATE table user_history ( runid decimal(21) null ,job_id decimal(21) null ,id varchar(100) not null ,user varchar(100) not null ,status varchar(10) not null ,event_time timestamp not null default now() ,comment varchar(1000) not null default 'none' ) ; """ result = create_models(ddl, models_type='pydantic_v2')['code'] # output: from __future__ import annotations import datetime from pydantic import BaseModel class UserHistory(BaseModel): runid: float | None = None job_id: float | None = None id: str user: str status: str event_time: datetime.datetime = datetime.datetime.now() comment: str = 'none'

Key differences in Pydantic v2 output:

  • Uses X | None instead of Optional[X]
  • Uses dict | list for JSON/JSONB types instead of Json
  • Includes from __future__ import annotations for Python 3.9 compatibility
  • Nullable fields automatically get = None default

To generate Dataclasses from DDL use argument models_type='dataclass'

for example:

python
# (same DDL as in Pydantic sample) result = create_models(ddl, schema_global=False, models_type='dataclass')['code'] # and result will be: import datetime from dataclasses import dataclass @dataclass class UserHistory: id: str user: str status: str runid: int = None job_id: int = None event_time: datetime.datetime = datetime.datetime.now() comment: str = 'none'

GinoORM example. If you provide an input like:

sql
CREATE TABLE "users" ( "id" SERIAL PRIMARY KEY, "name" varchar, "created_at" timestamp, "updated_at" timestamp, "country_code" int, "default_language" int ); CREATE TABLE "languages" ( "id" int PRIMARY KEY, "code" varchar(2) NOT NULL, "name" varchar NOT NULL );

and you will get output:

python
from gino import Gino db = Gino() class Users(db.Model): __tablename__ = 'users' id = db.Column(db.Integer(), autoincrement=True, primary_key=True) name = db.Column(db.String()) created_at = db.Column(db.TIMESTAMP()) updated_at = db.Column(db.TIMESTAMP()) country_code = db.Column(db.Integer()) default_language = db.Column(db.Integer()) class Languages(db.Model): __tablename__ = 'languages' id = db.Column(db.Integer(), primary_key=True) code = db.Column(db.String(2)) name = db.Column(db.String())

From cli

bash
omm path/to/your.ddl # for example omm tests/test_two_tables.sql

You can define target path where to save models with -t, --target flag:

bash
# for example omm tests/test_two_tables.sql -t test_path/test_models.py

If you want generate the Pydantic or Dataclasses models - just use flag -m or --models_type='pydantic' / --models_type='dataclass'

bash
omm /path/to/your.ddl -m dataclass # or omm /path/to/your.ddl --models_type pydantic

Small library is used for parse DDL- https://github.com/xnuinside/simple-ddl-parser.

What to do if types not supported in O!MyModels and you cannot wait until PR will be approved

First of all, to parse types correct from DDL to models - they must be in types mypping, for Gino it exitst in this file:

omymodels/gino/types.py types_mapping

If you need to use fast type that not exist in mapping - just do a path before call code with types_mapping.update()

for example:

python
from omymodels.models.gino import types from omymodels import create_models types.types_mapping.update({'your_type_from_ddl': 'db.TypeInGino'}) ddl = "YOUR DDL with your custom your_type_from_ddl" models = create_models(ddl) #### And similar for Pydantic types from omymodels.models.pydantic import types types_mapping from omymodels import create_models types.types_mapping.update({'your_type_from_ddl': 'db.TypeInGino'}) ddl = "YOUR DDL with your custom your_type_from_ddl" models = create_models(ddl, models_type='pydantic')

Schema defenition

There is 2 ways how to define schema in Models:

  1. Globally in Gino() class and it will be like this:
python
from gino import Gino db = Gino(schema="schema_name")

And this is a default way for put schema during generation - it takes first schema in tables and use it.

  1. But if you work with tables in different schemas, you need to define schema in each model in table_args. O!MyModels can do this also. Just use flag --no-global-schema if you use cli or put argument 'schema_global=False' to create_models() function if you use library from code. Like this:
python
ddl = """ CREATE TABLE "prefix--schema-name"."table" ( _id uuid PRIMARY KEY, one_more_id int ); create unique index table_pk on "prefix--schema-name"."table" (one_more_id) ; create index table_ix2 on "prefix--schema-name"."table" (_id) ; """ result = create_models(ddl, schema_global=False)

And result will be this:

python
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.schema import UniqueConstraint from sqlalchemy import Index from gino import Gino db = Gino() class Table(db.Model): __tablename__ = 'table' _id = db.Column(UUID, primary_key=True) one_more_id = db.Column(db.Integer()) __table_args__ = ( UniqueConstraint(one_more_id, name='table_pk'), Index('table_ix2', _id), dict(schema="prefix--schema-name") )

OpenAPI 3 (Swagger) Support

O!MyModels supports bidirectional conversion with OpenAPI 3 schemas.

Generate OpenAPI 3 schema from DDL

python
from omymodels import create_models ddl = """ CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(100) NOT NULL, email VARCHAR(255), is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP ); """ result = create_models(ddl, models_type="openapi3") print(result["code"]) # Output: # { # "components": { # "schemas": { # "Users": { # "type": "object", # "properties": { # "id": {"type": "integer"}, # "username": {"type": "string", "maxLength": 100}, # "email": {"type": "string", "maxLength": 255}, # "is_active": {"type": "boolean", "default": true}, # "created_at": {"type": "string", "format": "date-time"} # }, # "required": ["id", "username"] # } # } # } # }

Convert OpenAPI 3 schema to Python models

python
from omymodels import create_models_from_openapi3 schema = """ { "components": { "schemas": { "User": { "type": "object", "properties": { "id": {"type": "integer"}, "name": {"type": "string"}, "email": {"type": "string"}, "created_at": {"type": "string", "format": "date-time"} }, "required": ["id", "name"] } } } } """ # Convert to Pydantic v2 result = create_models_from_openapi3(schema, models_type="pydantic_v2") print(result) # Output: # from __future__ import annotations # # import datetime # from pydantic import BaseModel # # # class User(BaseModel): # # id: int # name: str # email: str | None = None # created_at: datetime.datetime | None = None

YAML schemas are also supported (requires pyyaml):

bash
pip install pyyaml

Custom Generators (Plugin System)

You can add support for your own model types without forking the repository.

Creating a Custom Generator

python
from omymodels import BaseGenerator, TypeConverter, register_generator, create_models # Define type mapping MY_TYPES = { "varchar": "String", "integer": "Integer", "boolean": "Boolean", "timestamp": "DateTime", } class MyGenerator(BaseGenerator): def __init__(self): super().__init__() self.type_converter = TypeConverter(MY_TYPES) def generate_model(self, table, singular=True, **kwargs): class_name = table.name.title().replace("_", "") lines = [f"class {class_name}(MyBaseModel):"] for column in table.columns: col_type = self.type_converter.convert(column.type) lines.append(f" {column.name}: {col_type}") return "\n".join(lines) def create_header(self, tables, **kwargs): return "from my_framework import MyBaseModel\n" # Register and use register_generator("my_framework", MyGenerator) result = create_models(ddl, models_type="my_framework")

Extending Built-in Generators

python
from omymodels import register_generator from omymodels.models.pydantic_v2.core import ModelGenerator as PydanticV2Generator class CustomPydanticGenerator(PydanticV2Generator): def create_header(self, *args, **kwargs): header = super().create_header(*args, **kwargs) return "from my_types import CustomType\n" + header register_generator("my_pydantic", CustomPydanticGenerator)

See full examples in example/custom_generator.py and example/extend_builtin_generator.py.

TODO in next releases

  1. Add Sequence generation in Models (Gino, SQLAlchemy)
  2. Add support for Tortoise ORM (https://tortoise-orm.readthedocs.io/en/latest/)
  3. Add support for DjangoORM Models
  4. Add support for PyDAL Models (https://py4web.com/_documentation/static/en/chapter-07.html)

How to contribute

Please describe issue that you want to solve and open the PR, I will review it as soon as possible.

Any questions? Ping me in Telegram: https://t.me/xnuinside or mail xnuinside@gmail.com

If you see any bugs or have any suggestions - feel free to open the issue. Any help will be appritiated.

Appretiation & thanks

One more time, big 'thank you!' goes to https://github.com/archongum for Web-version: https://archon-omymodels-online.hf.space/

Changelog

See CHANGELOG.md for full version history.

v1.0.0 Highlights

Breaking Changes:

  • Dropped support for Python 3.7 and 3.8
  • Minimum required Python version is now 3.9

New Features:

  • Pydantic v2 support with native syntax (X | None, dict | list)
  • OpenAPI 3 (Swagger) schema generation and conversion
  • Plugin system for custom generators
  • SQLModel array type support
  • MySQL blob types support

Improvements:

  • Simplified datetime imports
  • Better Pydantic field handling (aliases, reserved names, generated columns)
  • Enum functional syntax generation

See CHANGELOG.md for complete details and previous versions.

Contributors

Showing top 9 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from xnuinside/omymodels via the GitHub API.Last fetched: 6/25/2026