🚨 Active Supply Chain Attack:node-ipc Package Compromised.Learn More
Socket
Book a DemoSign in
Socket

sqlacodegen

Package Overview
Dependencies
Maintainers
2
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sqlacodegen - pypi Package Compare versions

Comparing version
3.2.0
to
4.0.0rc1
+13
.github/dependabot.yml
# Keep GitHub Actions up to date with GitHub's Dependabot...
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
version: 2
updates:
- package-ecosystem: github-actions
directory: /
groups:
github-actions:
patterns:
- "*" # Group all Actions updates into a single larger pull request
schedule:
interval: quarterly
tidelift: pypi/sqlacodegen
+8
-5

@@ -17,5 +17,5 @@ name: Publish packages to PyPI

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:

@@ -28,3 +28,3 @@ python-version: 3.x

- name: Archive packages
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:

@@ -43,3 +43,6 @@ name: dist

- name: Retrieve packages
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: dist
path: dist
- name: Upload packages

@@ -55,3 +58,3 @@ uses: pypa/gh-action-pypi-publish@release/v1

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- id: changelog

@@ -58,0 +61,0 @@ uses: agronholm/release-notes@v1

@@ -16,5 +16,5 @@ name: test suite

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:

@@ -26,3 +26,3 @@ python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: pip install -e .[test]
run: pip install --group test -e .[sqlmodel,citext,geoalchemy2,pgvector]
- name: Test with pytest

@@ -29,0 +29,0 @@ run: coverage run -m pytest

@@ -19,3 +19,3 @@ # This is the configuration file for pre-commit (https://pre-commit.com/).

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.13.3
rev: v0.14.10
hooks:

@@ -27,3 +27,3 @@ - id: ruff

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.18.2
rev: v1.19.1
hooks:

@@ -30,0 +30,0 @@ - id: mypy

Version history
===============
**4.0.0rc1**
- **BACKWARD INCOMPATIBLE** ``TablesGenerator.render_column_type()`` was changed to
receive the ``Column`` object instead of the column type object as its sole argument
- Added Python enum generation for native database ENUM types (e.g., PostgreSQL / MySQL ENUM).
Retained synthetic Python enum generation from CHECK constraints with
IN clauses (e.g., ``column IN ('val1', 'val2', ...)``). Use ``--options nonativeenums`` to
disable enum generation for native database enums. Use ``--options nosyntheticenums`` to
disable enum generation for synthetic database enums (VARCHAR columns with check constraints).
(PR by @sheinbergon)
**3.2.0**

@@ -5,0 +16,0 @@

Metadata-Version: 2.4
Name: sqlacodegen
Version: 3.2.0
Version: 4.0.0rc1
Summary: Automatic model code generator for SQLAlchemy

@@ -28,8 +28,2 @@ Author-email: Alex Grönholm <alex.gronholm@nextday.fi>

Requires-Dist: inflect>=4.0.0
Provides-Extra: test
Requires-Dist: sqlacodegen[geoalchemy2,pgvector,sqlmodel]; extra == "test"
Requires-Dist: pytest>=7.4; extra == "test"
Requires-Dist: coverage>=7; extra == "test"
Requires-Dist: psycopg[binary]; extra == "test"
Requires-Dist: mysql-connector-python; extra == "test"
Provides-Extra: sqlmodel

@@ -51,2 +45,5 @@ Requires-Dist: sqlmodel>=0.0.22; extra == "sqlmodel"

:alt: Code Coverage
.. image:: https://tidelift.com/badges/package/pypi/sqlacodegen
:target: https://tidelift.com/subscription/pkg/pypi-sqlacodegen
:alt: Tidelift

@@ -151,2 +148,4 @@ This is a tool that reads the structure of an existing database and generates the

* ``noindexes``: ignore indexes
* ``nonativeenums``: don't generate Python enum classes for native database ENUM types (e.g., PostgreSQL ENUM); use plain string mapping instead
* ``nosyntheticenums``: don't generate Python enum classes from CHECK constraints with IN clauses (e.g., ``column IN ('value1', 'value2', ...)``); preserves CHECK constraints as-is
* ``noidsuffix``: prevent the special naming logic for single column many-to-one

@@ -257,1 +256,9 @@ and one-to-one relationships (see `Relationship naming logic`_ for details)

.. _sqlalchemy: https://app.gitter.im/#/room/#sqlalchemy_community:gitter.im
Security contact information
============================
To report a security vulnerability, please use the `Tidelift security contact`_.
Tidelift will coordinate the fix and disclosure.
.. _Tidelift security contact: https://tidelift.com/security

@@ -42,9 +42,2 @@ [build-system]

[project.optional-dependencies]
test = [
"sqlacodegen[sqlmodel,pgvector,geoalchemy2]",
"pytest >= 7.4",
"coverage >= 7",
"psycopg[binary]",
"mysql-connector-python",
]
sqlmodel = ["sqlmodel >= 0.0.22"]

@@ -64,2 +57,10 @@ citext = ["sqlalchemy-citext >= 1.7.0"]

[dependency-groups]
test = [
"pytest >= 7.4",
"coverage >= 7",
"psycopg[binary]",
"mysql-connector-python",
]
[tool.setuptools_scm]

@@ -104,2 +105,3 @@ version_scheme = "post-release"

commands = [["python", "-m", "pytest", { replace = "posargs", extend = true }]]
extras = ["test"]
dependency_groups = ["test"]
extras = ["sqlmodel", "citext", "geoalchemy2", "pgvector"]

@@ -7,2 +7,5 @@ .. image:: https://github.com/agronholm/sqlacodegen/actions/workflows/test.yml/badge.svg

:alt: Code Coverage
.. image:: https://tidelift.com/badges/package/pypi/sqlacodegen
:target: https://tidelift.com/subscription/pkg/pypi-sqlacodegen
:alt: Tidelift

@@ -107,2 +110,4 @@ This is a tool that reads the structure of an existing database and generates the

* ``noindexes``: ignore indexes
* ``nonativeenums``: don't generate Python enum classes for native database ENUM types (e.g., PostgreSQL ENUM); use plain string mapping instead
* ``nosyntheticenums``: don't generate Python enum classes from CHECK constraints with IN clauses (e.g., ``column IN ('value1', 'value2', ...)``); preserves CHECK constraints as-is
* ``noidsuffix``: prevent the special naming logic for single column many-to-one

@@ -213,1 +218,9 @@ and one-to-one relationships (see `Relationship naming logic`_ for details)

.. _sqlalchemy: https://app.gitter.im/#/room/#sqlalchemy_community:gitter.im
Security contact information
============================
To report a security vulnerability, please use the `Tidelift security contact`_.
Tidelift will coordinate the fix and disclosure.
.. _Tidelift security contact: https://tidelift.com/security
Metadata-Version: 2.4
Name: sqlacodegen
Version: 3.2.0
Version: 4.0.0rc1
Summary: Automatic model code generator for SQLAlchemy

@@ -28,8 +28,2 @@ Author-email: Alex Grönholm <alex.gronholm@nextday.fi>

Requires-Dist: inflect>=4.0.0
Provides-Extra: test
Requires-Dist: sqlacodegen[geoalchemy2,pgvector,sqlmodel]; extra == "test"
Requires-Dist: pytest>=7.4; extra == "test"
Requires-Dist: coverage>=7; extra == "test"
Requires-Dist: psycopg[binary]; extra == "test"
Requires-Dist: mysql-connector-python; extra == "test"
Provides-Extra: sqlmodel

@@ -51,2 +45,5 @@ Requires-Dist: sqlmodel>=0.0.22; extra == "sqlmodel"

:alt: Code Coverage
.. image:: https://tidelift.com/badges/package/pypi/sqlacodegen
:target: https://tidelift.com/subscription/pkg/pypi-sqlacodegen
:alt: Tidelift

@@ -151,2 +148,4 @@ This is a tool that reads the structure of an existing database and generates the

* ``noindexes``: ignore indexes
* ``nonativeenums``: don't generate Python enum classes for native database ENUM types (e.g., PostgreSQL ENUM); use plain string mapping instead
* ``nosyntheticenums``: don't generate Python enum classes from CHECK constraints with IN clauses (e.g., ``column IN ('value1', 'value2', ...)``); preserves CHECK constraints as-is
* ``noidsuffix``: prevent the special naming logic for single column many-to-one

@@ -257,1 +256,9 @@ and one-to-one relationships (see `Relationship naming logic`_ for details)

.. _sqlalchemy: https://app.gitter.im/#/room/#sqlalchemy_community:gitter.im
Security contact information
============================
To report a security vulnerability, please use the `Tidelift security contact`_.
Tidelift will coordinate the fix and disclosure.
.. _Tidelift security contact: https://tidelift.com/security

@@ -15,8 +15,1 @@ SQLAlchemy>=2.0.29

sqlmodel>=0.0.22
[test]
sqlacodegen[geoalchemy2,pgvector,sqlmodel]
pytest>=7.4
coverage>=7
psycopg[binary]
mysql-connector-python

@@ -8,2 +8,4 @@ .gitignore

pyproject.toml
.github/FUNDING.yml
.github/dependabot.yml
.github/pull_request_template.md

@@ -10,0 +12,0 @@ .github/ISSUE_TEMPLATE/bug_report.yaml

@@ -213,8 +213,2 @@ from __future__ import annotations

def get_stdlib_module_names() -> set[str]:
major, minor = sys.version_info.major, sys.version_info.minor
if (major, minor) > (3, 9):
return set(sys.builtin_module_names) | set(sys.stdlib_module_names)
else:
from stdlib_list import stdlib_list
return set(sys.builtin_module_names) | set(stdlib_list(f"{major}.{minor}"))
return set(sys.builtin_module_names) | set(sys.stdlib_module_names)

@@ -207,1 +207,66 @@ from __future__ import annotations

)
def test_check_constraint_not_converted_to_enum(generator: CodeGenerator) -> None:
Table(
"users",
generator.metadata,
Column("id", INTEGER, primary_key=True),
Column("status", VARCHAR(20), nullable=False),
CheckConstraint("users.status IN ('active', 'inactive', 'pending')"),
)
# Recreate generator with nosyntheticenums option to preserve constraints
generator = SQLModelGenerator(
generator.metadata, generator.bind, ["nosyntheticenums"]
)
validate_code(
generator.generate(),
"""\
from sqlalchemy import CheckConstraint, Column, Integer, String
from sqlmodel import Field, SQLModel
class Users(SQLModel, table=True):
__table_args__ = (
CheckConstraint("users.status IN ('active', 'inactive', 'pending')"),
)
id: int = Field(sa_column=Column('id', Integer, primary_key=True))
status: str = Field(sa_column=Column('status', String(20), nullable=False))
""",
)
def test_synthetic_enum_generation(generator: CodeGenerator) -> None:
Table(
"accounts",
generator.metadata,
Column("id", INTEGER, primary_key=True),
Column("status", VARCHAR(20), nullable=False),
CheckConstraint("accounts.status IN ('active', 'inactive', 'pending')"),
)
validate_code(
generator.generate(),
"""\
import enum
from sqlalchemy import CheckConstraint, Column, Enum, Integer
from sqlmodel import Field, SQLModel
class AccountsStatus(str, enum.Enum):
ACTIVE = 'active'
INACTIVE = 'inactive'
PENDING = 'pending'
class Accounts(SQLModel, table=True):
__table_args__ = (
CheckConstraint("accounts.status IN ('active', 'inactive', 'pending')"),
)
id: int = Field(sa_column=Column('id', Integer, primary_key=True))
status: AccountsStatus = Field(sa_column=Column('status', Enum(AccountsStatus), nullable=False))
""",
)

@@ -63,2 +63,3 @@ from __future__ import annotations

from tests.test_generator_tables import TIMESTAMP_DECORATOR
import enum

@@ -71,5 +72,10 @@ from pgvector.sqlalchemy.vector import VECTOR

class Blah(str, enum.Enum):
A = 'A'
B = 'B'
t_simple_items = Table(
'simple_items', metadata,
Column('enum', Enum('A', 'B', name='blah', schema='someschema')),
Column('enum', Enum(Blah)),
Column('bool', Boolean),

@@ -207,3 +213,3 @@ Column('vector', VECTOR(3)),

def test_enum_detection(generator: CodeGenerator) -> None:
def test_check_constraint_preserved(generator: CodeGenerator) -> None:
Table(

@@ -216,6 +222,11 @@ "simple_items",

# Recreate generator with nosyntheticenums option to preserve constraints
generator = TablesGenerator(
generator.metadata, generator.bind, ["nosyntheticenums"]
)
validate_code(
generator.generate(),
"""\
from sqlalchemy import Column, Enum, MetaData, Table
from sqlalchemy import CheckConstraint, Column, MetaData, String, Table

@@ -227,3 +238,4 @@ metadata = MetaData()

'simple_items', metadata,
Column('enum', Enum('A', "\\\\'B", 'C'))
Column('enum', String(255)),
CheckConstraint("simple_items.enum IN ('A', '\\\\'B', 'C')")
)

@@ -234,2 +246,84 @@ """,

def test_synthetic_enum_generation(generator: CodeGenerator) -> None:
Table(
"simple_items",
generator.metadata,
Column("id", INTEGER, primary_key=True),
Column("status", VARCHAR(20)),
CheckConstraint("simple_items.status IN ('active', 'inactive', 'pending')"),
)
validate_code(
generator.generate(),
"""\
import enum
from sqlalchemy import CheckConstraint, Column, Enum, Integer, MetaData, Table
metadata = MetaData()
class SimpleItemsStatus(str, enum.Enum):
ACTIVE = 'active'
INACTIVE = 'inactive'
PENDING = 'pending'
t_simple_items = Table(
'simple_items', metadata,
Column('id', Integer, primary_key=True),
Column('status', Enum(SimpleItemsStatus)),
CheckConstraint("simple_items.status IN ('active', 'inactive', 'pending')")
)
""",
)
def test_enum_shared_values(generator: CodeGenerator) -> None:
from sqlalchemy import Enum as SAEnum
Table(
"users",
generator.metadata,
Column("id", INTEGER, primary_key=True),
Column("status", SAEnum("active", "inactive", "pending", name="status_enum")),
)
Table(
"accounts",
generator.metadata,
Column("id", INTEGER, primary_key=True),
Column("status", SAEnum("active", "inactive", "pending", name="status_enum")),
)
validate_code(
generator.generate(),
"""\
import enum
from sqlalchemy import Column, Enum, Integer, MetaData, Table
metadata = MetaData()
class StatusEnum(str, enum.Enum):
ACTIVE = 'active'
INACTIVE = 'inactive'
PENDING = 'pending'
t_accounts = Table(
'accounts', metadata,
Column('id', Integer, primary_key=True),
Column('status', Enum(StatusEnum))
)
t_users = Table(
'users', metadata,
Column('id', Integer, primary_key=True),
Column('status', Enum(StatusEnum))
)
""",
)
@pytest.mark.parametrize("engine", ["postgresql"], indirect=["engine"])

@@ -236,0 +330,0 @@ def test_domain_text(generator: CodeGenerator) -> None:

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display