SkillAgentSearch skills...

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.

Install / Use

/learn @xnuinside/Omymodels

README

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:

  • SQLAlchemy 2.0 ORM (https://docs.sqlalchemy.org/en/20/orm/) - modern syntax with Mapped and mapped_column
  • SQLAlchemy ORM (legacy style)
  • SQLAlchemy Core (Tables) (https://docs.sqlalchemy.org/en/20/core/metadata.html)
  • SQLModel (https://sqlmodel.tiangolo.com/) - combines SQLAlchemy and Pydantic
  • GinoORM (https://python-gino.org/)
  • Pydantic v1/v2 (https://docs.pydantic.dev/)
  • Python Dataclasses (https://docs.python.org/3/library/dataclasses.html)
  • Python Enum (https://docs.python.org/3/library/enum.html) - generated from DDL SQL Types
  • OpenAPI 3 (Swagger) schemas (https://swagger.io/specification/)

How to install


    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

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

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:

    #  (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:


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:


    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


    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:


    # 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'


    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:


    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:

    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:

    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:


    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

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 sch

View on GitHub
GitHub Stars198
CategoryData
Updated1mo ago
Forks25

Languages

Python

Security Score

100/100

Audited on Feb 3, 2026

No findings