From 0222fe522a9631fab0a6e6a84b680bcebc0a06c4 Mon Sep 17 00:00:00 2001 From: xnuinside Date: Sun, 18 Jan 2026 12:21:11 +0300 Subject: [PATCH 1/3] Add MySQL blob types support and test cases for issue #62 - Add tinyblob, blob, mediumblob, longblob to binary_types mapping - Add test_mysql_blob_types: verifies blob types map to bytes - Add test_mysql_all_common_types: comprehensive MySQL type coverage - Add test_mysql_default_null: verifies DEFAULT NULL handling for temporal types - Add CHANGELOG.md in Keep a Changelog format with full version history - Update README.md with link to CHANGELOG.md Relates to #62 --- CHANGELOG.md | 290 ++++++++++++++++++ README.md | 229 +------------- build.sh | 7 - omymodels/types/sql_types.py | 4 + .../generator/test_pydantic_models.py | 127 ++++++++ 5 files changed, 437 insertions(+), 220 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0620bf3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,290 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] - 2025-01-18 + +### Breaking Changes + +- Dropped support for Python 3.7 and 3.8 +- Minimum required Python version is now 3.9 + +### Added + +**Pydantic v2 Support** +- New `pydantic_v2` models type with native Pydantic v2 syntax +- Uses `X | None` instead of `Optional[X]` +- Uses `dict | list` for JSON/JSONB types instead of `Json` +- Adds `from __future__ import annotations` for Python 3.9 compatibility +- Nullable fields automatically get `= None` default + +**OpenAPI 3 (Swagger) Support** +- Generate OpenAPI 3 schemas from DDL: `create_models(ddl, models_type="openapi3")` +- Convert OpenAPI 3 schemas to Python models: `create_models_from_openapi3(schema)` +- Supports JSON and YAML input (with pyyaml) + +**Plugin System for Custom Generators** +- `register_generator()` - register custom generator +- `unregister_generator()` - remove custom generator +- `list_generators()` - list all available generators +- Base classes: `BaseGenerator`, `ORMGenerator`, `DataModelGenerator` +- `TypeConverter` class for type mappings +- Entry points support for auto-discovery +- See examples: `example/custom_generator.py`, `example/extend_builtin_generator.py` + +**Pydantic Improvements** +- Field alias support for invalid Python identifiers +- Handle Pydantic reserved names (copy, parse_obj, schema, etc.) +- Support for generated columns (`GENERATED ALWAYS AS`) with `exclude=True` +- `table_prefix` and `table_suffix` parameters for class name customization +- Boolean defaults 0/1 converted to False/True +- Expanded `datetime_now_check` with more SQL datetime keywords + +**SQLModel Improvements** +- Fixed array type generation (issue #66) +- Arrays now properly generate `List[T]` with correct SQLAlchemy ARRAY type +- Added `typing_imports` support for List import +- Added `pydantic_to_sa_fallback` mapping for array element types + +**MySQL Support** +- Added blob types support: `tinyblob`, `blob`, `mediumblob`, `longblob` map to `bytes` (issue #62) + +**Other** +- Added support for Python 3.12 and 3.13 +- Added tox configuration for local multi-version testing (py39-py313) +- Added pytest-cov for code coverage reporting + +### Changed + +- Simplified datetime imports (`from datetime import datetime` instead of `import datetime`) +- Use `Any` type instead of `Json` for json/jsonb columns in Pydantic +- Enum generation now uses functional syntax: `Enum(value='Name', names=[...])` +- Updated GitHub Actions workflow with latest action versions (checkout@v4, setup-python@v5) +- Updated py-models-parser to version 1.0.0 +- Reorganized types module with TypeConverter class + +### Fixed + +- Fixed `iterate_over_the_list()` modifying list during iteration +- Fixed meaningless condition in dataclass generator +- Fixed incorrect column type crash (PR #63) +- Fixed enums including whitespace in values (issue #69) +- Fixed boolean values capitalization - now generates `True`/`False` instead of `true`/`false` (PR #67) +- Fixed SQLModel array type generation TypeError (issue #66) +- Fixed MySQL blob types not mapping to `bytes` (issue #62) + +### Documentation + +- Added ARCHITECTURE.md with project documentation +- Updated documentation with Pydantic v2 examples + +## [0.17.0] + +### Fixed + +- Fix character varying type (issue #59) + +### Changed + +- SQLAlchemy import removed from generation in SQLModels if it is not used +- `= Field()` is not placed in SQLModel if there is no defaults or other settings + +## [0.16.0] + +### Added + +- Initial SQLModel Support + +## [0.15.1] + +### Changed + +- Foreign Key processing updates (PR #55) +- Move to simple-ddl-parser version 1.X + +## [0.14.0] + +### Added + +- Python 3.11 support + +## [0.13.0] + +### Added + +- Added argument `schema_global=` to support SQLAlchemy & Gino different table schemas (issue #41) + +## [0.12.1] + +### Fixed + +- `current_timestamp` function processed now same way as `now()` function from DDL + +## [0.12.0] + +### Fixed + +- Named arguments always go after positional (issue #35) + +### Added + +- Availability to disable auto-name conversion (issue #36) +- `no_auto_snake_case=True` keeps names 1-to-1 as in DDL file + +## [0.11.1] + +### Added + +- Added bytes type to pydantic (PR #31) + +### Changed + +- Parser version updated to the latest + +## [0.11.0] + +### Fixed + +- MSSQL column & table names in `[]` now parsed validly (issue #28) +- Names like `users_WorkSchedule` now converted correctly to PascalCase + +## [0.10.1] + +### Changed + +- Update simple-ddl-parser version to 0.21.2 + +## [0.10.0] + +### Changed + +- Meta models moved to separate package (table-meta) +- `common` module renamed to `from_ddl` + +### Fixed + +- Fixed bugs in converter (still in beta) +- Can generate Enum models if DDL has only CREATE TYPE statements +- String enums now inherit from `(str, Enum)` in all model types + +### Added + +- Converter feature to convert one model type to another (excluding SQLAlchemy Core Tables) + +## [0.9.0] + +### Added + +- Beta models converter from one type of models to another +- If O!MyModels does not know how to convert type - leaves it as is + +### Fixed + +- In Dataclass & Pydantic generators Decimals & Floats converted to float (previously was int) + +## [0.8.4] + +### Changed + +- If tables not found in DDL - raises NoTable error +- Added `exit_silent` flag for silent exit if no tables + +## [0.8.3] + +### Added + +- TableMetaModel class for unified metadata parsing + +### Fixed + +- `NOW()` recognized as `now()` (issue #18) +- Default value of `now()` uses field for dataclass (issue #19) + +## [0.8.1] + +### Fixed + +- Parser version updated (fixed several issues) +- Fixed Unique Constraint after schema in SQLAlchemy Core + +## [0.8.0] + +### Fixed + +- `--defaults-off` flag in CLI + +### Added + +- Support for SQLAlchemy Core Tables generating +- Added examples folder + +### Fixed + +- ForeignKey in SQLAlchemy + +## [0.7.0] + +### Added + +- SQLAlchemy models generation (defaults as 'server_default') +- Defaults for Pydantic models +- `defaults_off=True` flag and `--defaults-off` CLI flag + +### Fixed + +- Enum types with lower case names in DDLs +- Dataclass generation issues (default with datetime & Enums) +- Quotes not removed from defaults + +## [0.6.0] + +### Added + +- Python Dataclass generation from DDL +- ForeignKey generation to GinoORM Models with ondelete/onupdate support + +## [0.5.0] + +### Added + +- Enums/IntEnums types for Gino & Pydantic +- UUID type +- `schema_global` key (default True) +- `--no-global-schema` CLI flag + +### Changed + +- Primary key columns don't show nullable argument + +## [0.4.1] + +### Fixed + +- Table names containing multiple '-' + +## [0.4.0] + +### Added + +- Pydantic models generation from DDL + +### Changed + +- `create_gino_models` renamed to `create_models` + +## [0.3.0] + +### Fixed + +- Generated Index for 'index' statement (not unique constraint) +- Column size as tuple (4,2) + +## [0.2.0] + +### Added + +- Valid generating columns: autoincrement, default, type, arrays, unique, primary key +- Creating `__table_args__` for indexes diff --git a/README.md b/README.md index b474179..530cd05 100644 --- a/README.md +++ b/README.md @@ -498,222 +498,25 @@ If you see any bugs or have any suggestions - feel free to open the issue. Any h One more time, big 'thank you!' goes to https://github.com/archongum for Web-version: https://archon-omymodels-online.hf.space/ ## Changelog -**v1.0.0** -### Breaking Changes -1. Dropped support for Python 3.7 and 3.8 -2. Minimum required Python version is now 3.9 +See [CHANGELOG.md](CHANGELOG.md) for full version history. -### New Features -1. Added support for Python 3.12 and 3.13 -2. Added `pydantic_v2` models type with native Pydantic v2 syntax: - - Uses `X | None` instead of `Optional[X]` - - Uses `dict | list` for JSON/JSONB types instead of `Json` - - Adds `from __future__ import annotations` for Python 3.9 compatibility - - Nullable fields automatically get `= None` default -3. Added plugin system for custom generators - add your own model types without forking: - - `register_generator()` - register custom generator - - `unregister_generator()` - remove custom generator - - `list_generators()` - list all available generators - - Base classes: `BaseGenerator`, `ORMGenerator`, `DataModelGenerator` - - `TypeConverter` class for type mappings - - Entry points support for auto-discovery - - See examples: `example/custom_generator.py`, `example/extend_builtin_generator.py` -4. Added OpenAPI 3 (Swagger) schema support: - - Generate OpenAPI 3 schemas from DDL: `create_models(ddl, models_type="openapi3")` - - Convert OpenAPI 3 schemas to Python models: `create_models_from_openapi3(schema, models_type="pydantic_v2")` - - Supports JSON and YAML input (with pyyaml) -5. Added tox configuration for local multi-version testing (py39-py313) -6. Added pytest-cov for code coverage reporting +### v1.0.0 Highlights -### Improvements -1. Updated GitHub Actions workflow with latest action versions (checkout@v4, setup-python@v5) -2. Added ARCHITECTURE.md with project documentation -3. Updated documentation with Pydantic v2 examples -4. Reorganized types module with TypeConverter class -5. Updated py-models-parser to version 1.0.0 +**Breaking Changes:** +- Dropped support for Python 3.7 and 3.8 +- Minimum required Python version is now 3.9 -### Bug Fixes -1. Fixed `iterate_over_the_list()` modifying list during iteration -2. Fixed meaningless condition in dataclass generator +**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 -**v0.17.0** +**Improvements:** +- Simplified datetime imports +- Better Pydantic field handling (aliases, reserved names, generated columns) +- Enum functional syntax generation -### Updates -1. fix character varying type - https://github.com/xnuinside/omymodels/issues/59 -2. sqlalchemy import removed from generation in sqlmodels if it is not used -3. = Field() - is not placed in SQLModel if there is no defaults or other settings to the field - -**v0.16.0** - -### Updates -1. Initial SQLModel Support - - -**v0.15.1** -## Updates -1. Foreign Key processing updates - https://github.com/xnuinside/omymodels/pull/55 -2. Move to simple-ddl-parser version 1.X - -**v0.14.0** -## Updates - -1. Python 3.11 support. - - -**v0.13.0** -## New feature - -1. Added argument 'schema_global=' to support SQLAlchemy & Gino different table schemas https://github.com/xnuinside/omymodels/issues/41 - -**v0.12.1** -### Improvements - -1. current_timestamp function processed now same was as "now()" function from ddl - - -**v0.12.0** -### Fixes -1. Now named arguments always went after positional. Fix for https://github.com/xnuinside/omymodels/issues/35 - -### New feature: -1. Availability to disable auto-name convertion - https://github.com/xnuinside/omymodels/issues/36. -Now, if you want to keep names 1-to-1 as in your DDL file, you can set argument `no_auto_snake_case=True` and O!MyModels will do nothing with the table or column names. - - - -**v0.11.1** - -### Improvements: -1. added bytes type to pydantic - https://github.com/xnuinside/omymodels/pull/31 -2. parser version updated to the latest - - -**v0.11.0** - -### Fixes: - -1. MSSQL column & tables names in [] now is parsed validly - https://github.com/xnuinside/omymodels/issues/28 -2. names like 'users_WorkSchedule' now converted correctly to PascalCase like UsersWorkSchedule - - -**v0.10.1** -1. Update simple-ddl-parser version to 0.21.2 - - -**v0.10.0** -### Improvements: -1. Meta models moved to separate package - https://github.com/xnuinside/table-meta -2. `common` module renamed to `from_ddl`, but anyway please use public API as imports from main module: - -`from omymodels import create_models` or `from omymodels import convert_models` - -### Fixes: - -1. Fixed bunch of bugs in converter, but it stil in 'beta'. -2. Previously you can generate models if was any tables in ddl. Now you can also generate Enum models if in ddl you have only CREATE TYPE statements. -3. String enums now in any models types will be inherit from (str, Enum) - - -### Features: - -1. Added converter feature to convert one model type to another (excluding SQLAlchemy Core (Tables)). -Now with more tests for supported models, but still in Beta with bucnh of issues. - -**v0.9.0** -Features: -1. Added beta models converter from one type of models to another. -To use models convertor: - -```python -from omymodels import convert_models - - -models_from = """ - -class MaterialType(str, Enum): - - article = "article" - video = "video" - - -@dataclass -class Material: - - id: int - title: str - description: str - link: str - type: MaterialType - additional_properties: Union[dict, list] - created_at: datetime.datetime - updated_at: datetime.datetime - -""" - -result = convert_models(models_from, models_type="gino") -print(result) -``` - -where `models_type` - type of models that you want to get as a result - -2. Now if O!MyModels does not know how to convert type - he just leave it as is. - -Fixes: -1. In Dataclass & Pydantic generators now Decimals & Floats converted to float (previously was int). - -**v0.8.4** -1. Now if tables was not found in input DDL - models generator raise NoTable error. if you want to have still silent exit if no tables, please use flag: exit_silent - -**v0.8.3** -1. Added fundamental concept of TableMetaModel - class that unifies metadata parsed from different classes/ORM models types/DDLs to one standard to allow easy way convert one models to another -in next releases it will be used for converter from one type of models to another. -2. Fixed issue: https://github.com/xnuinside/omymodels/issues/18 "NOW() not recognized as now()" -3. Fixed issue: https://github.com/xnuinside/omymodels/issues/19 "Default value of now() always returns same time, use field for dataclass" - -**v0.8.1** -1. Parser version is updated (fixed several issues with generation) -2. Fixed issue with Unique Constraint after schema in SQLAlchemy Core - -**v0.8.0** -1. Fix --defaults-off flag in cli -2. Added support for SQLAlchemy Core Tables generating -3. Added examples folder in github `omymodels/example` -4. Fix issue with ForeignKey in SQLAlchemy - -**v0.7.0** -1. Added generation for SQLAlchemy models (defaults from DDLs are setting up as 'server_default') -2. Added defaults for Pydantic models -3. Added flag to generate Pydantic & Dataclass models WITHOUT defaults `defaults_off=True` (by default it is False). And cli flag --defaults-off -4. Fixed issue with Enum types with lower case names in DDLs -5. Fixed several issues with Dataclass generation (default with datetime & Enums) -6. '"' do not remove from defaults now - -**v0.6.0** -1. O!MyModels now also can generate python Dataclass from DDL. Use argument models_type='dataclass' or if you use the cli flag --models_type dataclass or -m dataclass -2. Added ForeignKey generation to GinoORM Models, added support for ondelete and onupdate - -**v0.5.0** -1. Added Enums/IntEnums types for Gino & Pydantic -2. Added UUID type -3. Added key `schema_global` in create_models method (by default schema_global = True). -If you set schema_global=False schema if it exists in ddl will be defined for each table (model) in table args. -This way you can have differen schemas per model (table). By default schema_global=True - this mean for all -table only one schema and it is defined in `db = Gino(schema="prefix--schema-name")`. -4. If column is a primary key (primary_key=True) nullable argument not showed, because primary keys always are not null. -5. To cli was added flag '--no-global-schema' to set schema in table_args. - -**v0.4.1** -1. Added correct work with table names contains multiple '-' - -**v0.4.0** -1. Added generation for Pydantic models from ddl -2. Main method create_gino_models renamed to create_models - -**v0.3.0** -1. Generated Index for 'index' statement in __table_args__ (not unique constrait as previously) -2. Fix issue with column size as tuple (4,2) - -**v0.2.0** -1. Valid generating columns in models: autoincrement, default, type, arrays, unique, primary key and etc. -2. Added creating __table_args__ for indexes +See [CHANGELOG.md](CHANGELOG.md) for complete details and previous versions. diff --git a/build.sh b/build.sh index b2503ea..6241e72 100755 --- a/build.sh +++ b/build.sh @@ -1,11 +1,4 @@ #!/bin/bash -# Build script for omymodels package - -# Merge changelog into README (keep full changelog in README.md for PyPI) -sed '/## Changelog/q' README.md > new_README.md -cat CHANGELOG.txt >> new_README.md -rm README.md -mv new_README.md README.md # Build package (PyPI supports Markdown directly via pyproject.toml readme field) rm -rf dist diff --git a/omymodels/types/sql_types.py b/omymodels/types/sql_types.py index 33339ea..17b63dd 100644 --- a/omymodels/types/sql_types.py +++ b/omymodels/types/sql_types.py @@ -23,6 +23,10 @@ "VARBINARY", "binary", "varbinary", + "tinyblob", + "blob", + "mediumblob", + "longblob", ) # JSON types diff --git a/tests/functional/generator/test_pydantic_models.py b/tests/functional/generator/test_pydantic_models.py index 3b1eed9..bfae2c8 100644 --- a/tests/functional/generator/test_pydantic_models.py +++ b/tests/functional/generator/test_pydantic_models.py @@ -193,3 +193,130 @@ class User(BaseModel): result = create_models(ddl, models_type="pydantic") assert expected == result["code"] + + +def test_mysql_blob_types(): + """Test that MySQL blob types are correctly mapped to bytes. + + Regression test for issue #62. + """ + ddl = """ +CREATE TABLE blob_test ( + col_tinyblob TINYBLOB, + col_blob BLOB, + col_mediumblob MEDIUMBLOB, + col_longblob LONGBLOB +); +""" + result = create_models(ddl, models_type="pydantic") + expected = """from typing import Optional +from pydantic import BaseModel + + +class BlobTest(BaseModel): + col_tinyblob: Optional[bytes] + col_blob: Optional[bytes] + col_mediumblob: Optional[bytes] + col_longblob: Optional[bytes] +""" + assert expected == result["code"] + + +def test_mysql_all_common_types(): + """Test comprehensive MySQL type support. + + Regression test for issue #62 - covers integer, decimal, temporal, + text, and binary types. + """ + ddl = """ +CREATE TABLE all_types ( + -- Integer types + col_tinyint TINYINT NOT NULL, + col_smallint SMALLINT, + col_mediumint MEDIUMINT, + col_int INT, + col_bigint BIGINT, + + -- Decimal types + col_decimal DECIMAL(10,2), + col_float FLOAT, + col_double DOUBLE, + + -- Temporal types + col_date DATE, + col_datetime DATETIME, + col_timestamp TIMESTAMP, + col_time TIME, + col_year YEAR, + + -- Text types + col_char CHAR(10), + col_varchar VARCHAR(255), + col_tinytext TINYTEXT, + col_text TEXT, + col_mediumtext MEDIUMTEXT, + col_longtext LONGTEXT, + + -- Binary types + col_binary BINARY(10), + col_varbinary VARBINARY(255), + col_tinyblob TINYBLOB, + col_blob BLOB, + col_mediumblob MEDIUMBLOB, + col_longblob LONGBLOB, + + -- JSON type + col_json JSON +); +""" + result = create_models(ddl, models_type="pydantic") + + # Verify key type mappings + code = result["code"] + assert "col_tinyint: int" in code + assert "col_smallint: Optional[int]" in code + assert "col_bigint: Optional[int]" in code + assert "col_decimal: Optional[float]" in code + assert "col_float: Optional[float]" in code + assert "col_double: Optional[float]" in code + assert "col_date: Optional[date]" in code + assert "col_datetime: Optional[datetime]" in code + assert "col_timestamp: Optional[datetime]" in code + assert "col_time: Optional[time]" in code + assert "col_year: Optional[int]" in code + assert "col_char: Optional[str]" in code + assert "col_varchar: Optional[str]" in code + assert "col_text: Optional[str]" in code + assert "col_binary: Optional[bytes]" in code + assert "col_varbinary: Optional[bytes]" in code + assert "col_tinyblob: Optional[bytes]" in code + assert "col_blob: Optional[bytes]" in code + assert "col_mediumblob: Optional[bytes]" in code + assert "col_longblob: Optional[bytes]" in code + assert "col_json: Optional[Any]" in code + + +def test_mysql_default_null(): + """Test that DEFAULT NULL is handled correctly for temporal types. + + Regression test for issue #62. + """ + ddl = """ +CREATE TABLE test_defaults ( + col_date DATE DEFAULT NULL, + col_datetime DATETIME DEFAULT NULL, + col_timestamp TIMESTAMP DEFAULT NULL +); +""" + result = create_models(ddl, models_type="pydantic") + expected = """from datetime import datetime, date +from typing import Optional +from pydantic import BaseModel + + +class TestDefaults(BaseModel): + col_date: Optional[date] + col_datetime: Optional[datetime] + col_timestamp: Optional[datetime] +""" + assert expected == result["code"] From 63fe1c4b6a59242770259b1f849f53664ed8ea9e Mon Sep 17 00:00:00 2001 From: xnuinside Date: Sun, 18 Jan 2026 12:28:45 +0300 Subject: [PATCH 2/3] Add GitHub Pages promo site with interactive demo - Add docs/index.html with interactive demo page: - Visual DDL to Python models conversion demo - Switchable output formats (pydantic, pydantic_v2, sqlalchemy, sqlmodel, dataclass) - Supported model types showcase - Quick start guide (3 steps) - Features overview - Dark theme with syntax highlighting - Add GitHub Pages deployment to CI/CD pipeline: - Deploys on push to main after tests pass - Uses actions/deploy-pages@v4 - Update README with link to interactive demo --- .github/workflows/main.yml | 28 +- README.md | 3 +- docs/index.html | 760 +++++++++++++++++++++++++++++++++++++ 3 files changed, 789 insertions(+), 2 deletions(-) create mode 100644 docs/index.html diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd6854b..4a10747 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,4 +52,30 @@ jobs: with: files: ./coverage.xml fail_ci_if_error: false - verbose: true \ No newline at end of file + verbose: true + + deploy-pages: + runs-on: ubuntu-latest + needs: [tests] + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + permissions: + contents: read + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v4 + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: './docs' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/README.md b/README.md index 530cd05..e5900bc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ ## O! My Models -![badge1](https://img.shields.io/pypi/v/omymodels) ![badge2](https://img.shields.io/pypi/l/omymodels) ![badge3](https://img.shields.io/pypi/pyversions/omymodels)![workflow](https://github.com/xnuinside/omymodels/actions/workflows/main.yml/badge.svg) +![badge1](https://img.shields.io/pypi/v/omymodels) ![badge2](https://img.shields.io/pypi/l/omymodels) ![badge3](https://img.shields.io/pypi/pyversions/omymodels) ![workflow](https://github.com/xnuinside/omymodels/actions/workflows/main.yml/badge.svg) +**[Interactive Demo](https://xnuinside.github.io/omymodels/)** | **[Documentation](https://github.com/xnuinside/omymodels#how-to-use)** | **[PyPI](https://pypi.org/project/omymodels/)** ## 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) diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..26f66e8 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,760 @@ + + + + + + O! My Models - DDL to Python Models Generator + + + + + + +
+ +
+ +
+
+

SQL DDL to Python Models

+

Generate Pydantic, SQLAlchemy, SQLModel, Dataclasses and more from your database schema in seconds

+ +
+
+ +
+
+

See It In Action

+

Paste your SQL, get Python models instantly

+ +
+ + + + + +
+ +
+
+
+ SQL DDL +
+
+
CREATE TABLE "users" (
+  "id" SERIAL PRIMARY KEY,
+  "email" VARCHAR(255) NOT NULL,
+  "name" VARCHAR(100),
+  "is_active" BOOLEAN DEFAULT TRUE,
+  "created_at" TIMESTAMP DEFAULT NOW()
+);
+
+
+ +
+ + + + + omymodels +
+ +
+
+ Python Model +
+
+
+
from datetime import datetime
+from typing import Optional
+from pydantic import BaseModel
+
+
+class Users(BaseModel):
+    id: int
+    email: str
+    name: Optional[str]
+    is_active: Optional[bool] = True
+    created_at: Optional[datetime] = datetime.now()
+
+
+
from __future__ import annotations
+import datetime
+from pydantic import BaseModel
+
+
+class Users(BaseModel):
+    id: int
+    email: str
+    name: str | None = None
+    is_active: bool | None = True
+    created_at: datetime.datetime | None = datetime.datetime.now()
+
+
+
import sqlalchemy as sa
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.sql import func
+
+Base = declarative_base()
+
+
+class Users(Base):
+    __tablename__ = 'users'
+
+    id = sa.Column(sa.Integer(), primary_key=True)
+    email = sa.Column(sa.String(255), nullable=False)
+    name = sa.Column(sa.String(100))
+    is_active = sa.Column(sa.Boolean(), server_default='true')
+    created_at = sa.Column(sa.TIMESTAMP(), server_default=func.now())
+
+
+
import datetime
+from typing import Optional
+from sqlmodel import Field, SQLModel
+from sqlalchemy.sql import func
+
+
+class Users(SQLModel, table=True):
+    __tablename__ = 'users'
+
+    id: Optional[int] = Field(default=None, primary_key=True)
+    email: str
+    name: Optional[str]
+    is_active: Optional[bool] = Field(server_default='true')
+    created_at: Optional[datetime.datetime] = Field(server_default=func.now())
+
+
+
import datetime
+from dataclasses import dataclass, field
+
+
+@dataclass
+class Users:
+    id: int
+    email: str
+    name: str = None
+    is_active: bool = True
+    created_at: datetime.datetime = field(
+        default_factory=datetime.datetime.now
+    )
+
+
+
+
+
+
+ +
+
+

Supported Output Formats

+

One DDL, many possibilities

+ +
+
+
๐Ÿ”ท
+

Pydantic v1

+ pydantic +
+
+
๐Ÿ”ถ
+

Pydantic v2

+ pydantic_v2 +
+
+
๐Ÿ—„๏ธ
+

SQLAlchemy ORM

+ sqlalchemy +
+
+
โšก
+

SQLModel

+ sqlmodel +
+
+
๐Ÿ“ฆ
+

Dataclasses

+ dataclass +
+
+
๐Ÿฆ„
+

GinoORM

+ gino +
+
+
๐Ÿ“‹
+

OpenAPI 3

+ openapi3 +
+
+
๐Ÿ”ง
+

SQLAlchemy Core

+ sqlalchemy_core +
+
+
+
+ +
+
+

Quick Start

+

Get started in 3 simple steps

+ +
+
+
1
+

Install

+

Install via pip in seconds

+
+ pip install omymodels +
+
+ +
+
2
+

Use in Python

+

Import and generate models

+
+
from omymodels import create_models
+
+result = create_models(
+    ddl,
+    models_type="pydantic_v2"
+)
+print(result["code"])
+
+
+ +
+
3
+

Or Use CLI

+

Generate directly from terminal

+
+
# Generate Pydantic v2 models
+omm schema.sql -m pydantic_v2 -t models.py
+
+# Generate SQLModel
+omm schema.sql -m sqlmodel -t models.py
+
+
+
+
+
+ +
+
+

Features

+

Everything you need for model generation

+ +
+
+
๐Ÿ”„
+

Bidirectional Conversion

+

Convert between different model types. Turn Pydantic into SQLAlchemy or vice versa.

+
+
+
๐Ÿ“
+

Enum Support

+

Automatically generates Python Enums from SQL ENUM and TYPE definitions.

+
+
+
๐Ÿ”—
+

Foreign Keys

+

Preserves relationships with proper foreign key references and constraints.

+
+
+
โš™๏ธ
+

Defaults & Constraints

+

Handles default values, nullable fields, and other column constraints.

+
+
+
๐Ÿ”Œ
+

Plugin System

+

Create custom generators for your own frameworks without forking.

+
+
+
๐ŸŒ
+

OpenAPI Support

+

Generate OpenAPI 3 schemas or convert them to Python models.

+
+
+
+
+ + + + + + From d6b9817a52b9baf3166fe75c8155c41fb7308581 Mon Sep 17 00:00:00 2001 From: xnuinside Date: Sun, 18 Jan 2026 12:31:40 +0300 Subject: [PATCH 3/3] Add disclaimer about Web UI version --- docs/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 26f66e8..9d98723 100644 --- a/docs/index.html +++ b/docs/index.html @@ -462,11 +462,14 @@

SQL DDL to Python Models

pip install omymodels - + Try Online +

+ * Web UI version may differ from the latest release +