Skip to content

Commit 7efa358

Browse files
authored
Add SQLAlchemy 2.0 support (issue #49) (#75)
* Add SQLAlchemy 2.0 support (issue #49) - New sqlalchemy_v2 generator with modern SQLAlchemy 2.0 syntax: - Uses DeclarativeBase instead of deprecated declarative_base() - Uses Mapped[T] type annotations for columns - Uses mapped_column() instead of Column() - Uses X | None union syntax for nullable columns - Support for all column types, foreign keys, indexes, and constraints - Added functional tests for SQLAlchemy v2 generation - Added integration tests for SQLAlchemy v2 (validates generated code runs) - Added integration tests for OpenAPI 3 generator - Updated CHANGELOG.md and README.md with SQLAlchemy v2 support - Removed unused files (SUGGESTIONS.md, one.ddl) * Add SQLAlchemy as test dependency for integration tests * Fix tox coverage by using usedevelop=true * Add integration tests for all model generators - dataclass: 4 tests for basic model, fields, defaults, multiple tables - sqlalchemy (legacy): 4 tests for basic model, columns, FK, multiple tables - sqlalchemy_core: 5 tests (skipped - generator has known bugs) - sqlmodel: 4 tests (skipped - requires Pydantic>=2.0, conflicts with table-meta) - gino: 4 tests (skipped - requires SQLAlchemy<1.4, conflicts with SQLAlchemy>=2.0) Note: Some tests are skipped due to dependency conflicts: - sqlmodel requires pydantic>=2.0, but table-meta requires pydantic<2.0 - gino requires sqlalchemy<1.4, but we use sqlalchemy>=2.0 - sqlalchemy_core generator has bugs (missing column names, broken type sizes) * Run integration tests in isolated tox/CI environments - Separate tox environments for different dependency requirements: - py39-py313: unit and functional tests - integration-sqlalchemy: pydantic v1, sqlalchemy v2 - integration-gino: pydantic v1, sqlalchemy v1.3 (gino requirement) - Separate CI jobs for each integration test group - SQLModel integration tests disabled due to unresolvable conflict: - sqlmodel requires pydantic>=2.0 - table-meta requires pydantic<2.0 - Tests will be skipped until table-meta adds pydantic 2.x support * Fix SQLModel integration tests to not depend on omymodels Integration tests now use pre-generated code fixtures instead of calling create_models() at runtime. This allows SQLModel tests to run in an isolated environment with pydantic>=2.0 without conflicts. Tests verify that the generated code (as users would commit to their repos) works correctly with the target library. * Fix sqlalchemy_core generator bugs and isolate gino tests - Fix sqlalchemy_core generator: add column names to output - Fix sqlalchemy_core generator: include type name with size - Fix sqlalchemy_core generator: correct positional/keyword arg order for ForeignKey - Convert gino tests to pre-generated code fixtures (no omymodels dependency) - Update tox.ini and CI workflow for isolated gino tests - Remove flawed parametrized converter test (py-models-parser limitations) - Update functional test expected values for sqlalchemy_core * Update CHANGELOG with sqlalchemy_core fixes
1 parent 50db95a commit 7efa358

38 files changed

+2175
-1017
lines changed

.github/workflows/main.yml

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
run: |
2525
flake8 omymodels/ --count --show-source --statistics
2626
27+
# Unit and functional tests
2728
tests:
2829
runs-on: ubuntu-latest
2930
needs: [flake8_py3]
@@ -43,9 +44,9 @@ jobs:
4344
poetry install
4445
env:
4546
POETRY_VIRTUALENVS_CREATE: false
46-
- name: Test with pytest and coverage
47+
- name: Run unit and functional tests
4748
run: |
48-
pytest tests/ -vv --cov=omymodels --cov-report=term-missing --cov-report=xml
49+
pytest tests/unit tests/functional -vv --cov=omymodels --cov-report=term-missing --cov-report=xml
4950
- name: Upload coverage to Codecov
5051
if: matrix.python == '3.11'
5152
uses: codecov/codecov-action@v4
@@ -54,6 +55,63 @@ jobs:
5455
fail_ci_if_error: false
5556
verbose: true
5657

58+
# Integration tests with SQLAlchemy 2.0 (pydantic, pydantic_v2, dataclass, sqlalchemy, sqlalchemy_v2, openapi3)
59+
integration-sqlalchemy:
60+
runs-on: ubuntu-latest
61+
needs: [flake8_py3]
62+
steps:
63+
- uses: actions/checkout@v4
64+
- name: Set up Python 3.11
65+
uses: actions/setup-python@v5
66+
with:
67+
python-version: '3.11'
68+
- name: Install dependencies
69+
run: |
70+
python -m pip install --upgrade pip
71+
pip install pytest simple-ddl-parser Jinja2 py-models-parser 'pydantic>=1.8.2,<2.0.0' table-meta 'sqlalchemy>=2.0'
72+
pip install -e .
73+
- name: Run SQLAlchemy integration tests
74+
run: |
75+
pytest tests/integration/pydantic tests/integration/pydantic_v2 tests/integration/dataclass tests/integration/sqlalchemy tests/integration/sqlalchemy_v2 tests/integration/openapi3 -vv
76+
77+
# Integration tests with Gino (requires SQLAlchemy<1.4)
78+
# Tests use pre-generated code fixtures, no omymodels dependency at runtime
79+
integration-gino:
80+
runs-on: ubuntu-latest
81+
needs: [flake8_py3]
82+
steps:
83+
- uses: actions/checkout@v4
84+
- name: Set up Python 3.11
85+
uses: actions/setup-python@v5
86+
with:
87+
python-version: '3.11'
88+
- name: Install dependencies
89+
run: |
90+
python -m pip install --upgrade pip
91+
pip install pytest 'gino>=1.0.0'
92+
- name: Run Gino integration tests
93+
run: |
94+
pytest tests/integration/gino -vv
95+
96+
# Integration tests with SQLModel (requires Pydantic>=2.0)
97+
# Tests use pre-generated code fixtures, no omymodels dependency at runtime
98+
integration-sqlmodel:
99+
runs-on: ubuntu-latest
100+
needs: [flake8_py3]
101+
steps:
102+
- uses: actions/checkout@v4
103+
- name: Set up Python 3.11
104+
uses: actions/setup-python@v5
105+
with:
106+
python-version: '3.11'
107+
- name: Install dependencies
108+
run: |
109+
python -m pip install --upgrade pip
110+
pip install pytest 'sqlmodel>=0.0.22'
111+
- name: Run SQLModel integration tests
112+
run: |
113+
pytest tests/integration/sqlmodel -vv
114+
57115
deploy-pages:
58116
runs-on: ubuntu-latest
59117
needs: [tests]
@@ -78,4 +136,4 @@ jobs:
78136

79137
- name: Deploy to GitHub Pages
80138
id: deployment
81-
uses: actions/deploy-pages@v4
139+
uses: actions/deploy-pages@v4

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4343
- Boolean defaults 0/1 converted to False/True
4444
- Expanded `datetime_now_check` with more SQL datetime keywords
4545

46+
**SQLAlchemy 2.0 Support (issue #49)**
47+
- New `sqlalchemy_v2` models type with modern SQLAlchemy 2.0 syntax
48+
- Uses `DeclarativeBase` instead of deprecated `declarative_base()`
49+
- Uses `Mapped[T]` type annotations for columns
50+
- Uses `mapped_column()` instead of `Column()`
51+
- Uses `X | None` union syntax for nullable columns
52+
- Supports all column types, foreign keys, indexes, and constraints
53+
4654
**SQLModel Improvements**
4755
- Fixed array type generation (issue #66)
4856
- Arrays now properly generate `List[T]` with correct SQLAlchemy ARRAY type
@@ -75,6 +83,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7583
- Fixed boolean values capitalization - now generates `True`/`False` instead of `true`/`false` (PR #67)
7684
- Fixed SQLModel array type generation TypeError (issue #66)
7785
- Fixed MySQL blob types not mapping to `bytes` (issue #62)
86+
- Fixed `sqlalchemy_core` generator missing column names in output
87+
- Fixed `sqlalchemy_core` generator not including type name with size (e.g., `String(255)`)
88+
- Fixed `sqlalchemy_core` generator ForeignKey positional argument order
7889

7990
### Documentation
8091

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ O! My Models (omymodels) is a library that allow you to **generate** different O
1616

1717
Supported Models:
1818

19-
- SQLAlchemy ORM (https://docs.sqlalchemy.org/en/20/orm/)
19+
- SQLAlchemy 2.0 ORM (https://docs.sqlalchemy.org/en/20/orm/) - modern syntax with `Mapped` and `mapped_column`
20+
- SQLAlchemy ORM (legacy style)
2021
- SQLAlchemy Core (Tables) (https://docs.sqlalchemy.org/en/20/core/metadata.html)
2122
- SQLModel (https://sqlmodel.tiangolo.com/) - combines SQLAlchemy and Pydantic
2223
- GinoORM (https://python-gino.org/)

0 commit comments

Comments
 (0)