All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Dropped support for Python 3.7 and 3.8
- Minimum required Python version is now 3.9
Pydantic v2 Support
- New
pydantic_v2models type with native Pydantic v2 syntax - Uses
X | Noneinstead ofOptional[X] - Uses
dict | listfor JSON/JSONB types instead ofJson - Adds
from __future__ import annotationsfor Python 3.9 compatibility - Nullable fields automatically get
= Nonedefault
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 generatorunregister_generator()- remove custom generatorlist_generators()- list all available generators- Base classes:
BaseGenerator,ORMGenerator,DataModelGenerator TypeConverterclass 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) withexclude=True table_prefixandtable_suffixparameters for class name customization- Boolean defaults 0/1 converted to False/True
- Expanded
datetime_now_checkwith more SQL datetime keywords - VARCHAR(n) and CHAR(n) now generate
Field(max_length=n)for Pydantic validation (issue #48)
SQLAlchemy 2.0 Support (issue #49)
- New
sqlalchemy_v2models type with modern SQLAlchemy 2.0 syntax - Uses
DeclarativeBaseinstead of deprecateddeclarative_base() - Uses
Mapped[T]type annotations for columns - Uses
mapped_column()instead ofColumn() - Uses
X | Noneunion syntax for nullable columns - Supports all column types, foreign keys, indexes, and constraints
SQLAlchemy Relationships (issue #47)
- New
relationshipsparameter forcreate_models()to generaterelationship()withback_populates - Automatically generates bidirectional relationships for foreign keys:
- Parent side (one-to-many): collection attribute pointing to children
- Child side (many-to-one): attribute pointing to parent
- Works with both
sqlalchemyandsqlalchemy_v2model types - For
sqlalchemy_v2: usesMapped[List[T]]for one-to-many andMapped[T]for many-to-one
Schema-Separated Model Files (issue #40)
- New
split_by_schemaparameter forcreate_models()to generate separate files per database schema - Each schema gets its own file with a schema-specific Base class (e.g.,
Schema1Base) - Tables without explicit schema go to a file with the default
Baseclass - Works with both
sqlalchemyandsqlalchemy_v2model types - File naming:
{schema_name}_{base_filename}.py(e.g.,schema1_models.py)
Pydal Model Conversion (issue #30)
- Convert Pydal table definitions to any supported model type using
convert_models() - Supports all output formats: SQLAlchemy, SQLAlchemy v2, Gino, Pydantic, Pydantic v2, Dataclass, SQLModel
- Handles Pydal types:
id,string,text,integer,boolean,datetime,date,float,decimal - Pydal's
idtype maps to primary key - Pydal's
reference table_nametype maps to foreign key
SQLModel Improvements
- Fixed array type generation (issue #66)
- Arrays now properly generate
List[T]with correct SQLAlchemy ARRAY type - Added
typing_importssupport for List import - Added
pydantic_to_sa_fallbackmapping for array element types
MySQL Support
- Added blob types support:
tinyblob,blob,mediumblob,longblobmap tobytes(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
- Simplified datetime imports (
from datetime import datetimeinstead ofimport datetime) - Use
Anytype instead ofJsonfor 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 dependency conflict with simple-ddl-generator: relaxed
table-metaconstraint to>=0.1.5(issue #46) - 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/Falseinstead oftrue/false(PR #67) - Fixed SQLModel array type generation TypeError (issue #66)
- Fixed MySQL blob types not mapping to
bytes(issue #62) - Fixed
sqlalchemy_coregenerator missing column names in output - Fixed
sqlalchemy_coregenerator not including type name with size (e.g.,String(255)) - Fixed
sqlalchemy_coregenerator ForeignKey positional argument order
- Added ARCHITECTURE.md with project documentation
- Updated documentation with Pydantic v2 examples
- Fix character varying type (issue #59)
- 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
- Initial SQLModel Support
- Foreign Key processing updates (PR #55)
- Move to simple-ddl-parser version 1.X
- Python 3.11 support
- Added argument
schema_global=to support SQLAlchemy & Gino different table schemas (issue #41)
current_timestampfunction processed now same way asnow()function from DDL
- Named arguments always go after positional (issue #35)
- Availability to disable auto-name conversion (issue #36)
no_auto_snake_case=Truekeeps names 1-to-1 as in DDL file
- Added bytes type to pydantic (PR #31)
- Parser version updated to the latest
- MSSQL column & table names in
[]now parsed validly (issue #28) - Names like
users_WorkSchedulenow converted correctly to PascalCase
- Update simple-ddl-parser version to 0.21.2
- Meta models moved to separate package (table-meta)
commonmodule renamed tofrom_ddl
- 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
- Converter feature to convert one model type to another (excluding SQLAlchemy Core Tables)
- Beta models converter from one type of models to another
- If O!MyModels does not know how to convert type - leaves it as is
- In Dataclass & Pydantic generators Decimals & Floats converted to float (previously was int)
- If tables not found in DDL - raises NoTable error
- Added
exit_silentflag for silent exit if no tables
- TableMetaModel class for unified metadata parsing
NOW()recognized asnow()(issue #18)- Default value of
now()uses field for dataclass (issue #19)
- Parser version updated (fixed several issues)
- Fixed Unique Constraint after schema in SQLAlchemy Core
--defaults-offflag in CLI
- Support for SQLAlchemy Core Tables generating
- Added examples folder
- ForeignKey in SQLAlchemy
- SQLAlchemy models generation (defaults as 'server_default')
- Defaults for Pydantic models
defaults_off=Trueflag and--defaults-offCLI flag
- Enum types with lower case names in DDLs
- Dataclass generation issues (default with datetime & Enums)
- Quotes not removed from defaults
- Python Dataclass generation from DDL
- ForeignKey generation to GinoORM Models with ondelete/onupdate support
- Enums/IntEnums types for Gino & Pydantic
- UUID type
schema_globalkey (default True)--no-global-schemaCLI flag
- Primary key columns don't show nullable argument
- Table names containing multiple '-'
- Pydantic models generation from DDL
create_gino_modelsrenamed tocreate_models
- Generated Index for 'index' statement (not unique constraint)
- Column size as tuple (4,2)
- Valid generating columns: autoincrement, default, type, arrays, unique, primary key
- Creating
__table_args__for indexes