Skip to content

Conversation

@jaogoy
Copy link

@jaogoy jaogoy commented Nov 17, 2025

Summary

  • Render Table/Column dialect-specific kwargs and info in generated code.
  • Add include-dialect-options and keep-dialect-types option to render dialect options and preserve dialect-specific column types instead of adapting to generic SQLAlchemy types.

Motivation

  • Some dialect features (e.g., engine/storage params, partitioning, materialized view metadata) are carried in SQLAlchemy dialect_kwargs or info but weren’t emitted by sqlacodegen.
    • include-dialect-options is a must for any dialect with any dialect options.
  • For custom dialects with their own Column types, the current type “adaptation” step collapses them into generic SQLAlchemy types, losing fidelity.
    • Without keep-dialect-types, sqlacodegen will render sqlatype.Integer for dialect's INTEGER if it inherits the sqlatype.Integer (for example). Then, when using Alembic (a Schema Migration Tool), it will compare the table schema in database and the table scheme defined in the metadata python file, which will be probably generated by using sqlacodegen for the initial stage, and modified by users manually to add or change some tables. If users write the metadta script with dialect's types (such as INTEGER), then Alembic will recoganize that there are differenct (one is sqlatype.Integer, and the other is dialect.INTEGER), it will generate an alter_table(...) operations, what is not expected by users.
    • So, with keep-dialect-types, sqlacodegen will render the dialect's types (such as dialect.INTEGER), then Alembic won't generate unnecessary altering operations.

What’s changed

  • Render dialect kwargs and info

  • Table (Core): include table-level dialect_kwargs and info in Table(...) kwargs.

  • Column (Core/ORM): include column-level dialect_kwargs and info in Column(...) / mapped_column(...).

  • Declarative: include table-level dialect_kwargs and info in __table_args__ dict.

  • New option: include-dialect-options, keep-dialect-types

  • Behavior: gates only the type adaptation step in fix_column_types(); Boolean/Enum inference and PostgreSQL sequence handling remain intact.

Usage examples

  • Core (Table)
t_orders = Table(
    'orders',
    metadata,
    Column('id', INTEGER, primary_key=True),
    Column('count', INTEGER, starrocks_aggr_type='SUM'),
    schema='public',
    comment='orders table',
    info={'table_kind': 'view', 'definition':'select id, sum(count) as count from orders_table'},
    starrocks_properties={'replication_num': '1'},
)
  • Declarative (__table_args__)
class Orders(Base):
    __tablename__ = 'orders'
    __table_args__ = {
        'schema': 'public',
        'comment': 'orders table',
        'info': {'table_kind': 'view', 'definition':'select id, sum(count) as count from orders_table'},
        'starrocks_properties': {'replication_num': '1'},
    }
    id: Mapped[Optional[int]] = mapped_column(INTEGER, primary_key=True)
    count: Mapped[Optional[int]] = mapped_column(INTEGER, starrocks_aggr_type='SUM')
  • Preserve dialect types
sqlacodegen starrocks://... --options=include-dialect-options,keep-dialect-types

When the include-dialect-options flag is set, it will render the dialect options (e.g. starrocks_properties) and info dict (which will store the table_kind, to indicate it's a table or a view/mv, and the definition for a view/mv).

When the keep-dialect-types flag is set, dialect-specific types (e.g., starrocks.datatype.INTEGER) are preserved and imported from their original module rather than adapted to generic SQLAlchemy types.

Backward compatibility

  • Default behavior is unchanged:
  • If include-dialect-options is not set, type dialect options and info will not be rendered as before.
  • If keep-dialect-types is not set, type adaptation continues as before.
  • No breaking API changes.

Changes

Fixes #.

Checklist

If this is a user-facing code change, like a bugfix or a new feature, please ensure that
you've fulfilled the following conditions (where applicable):

  • You've added tests (in tests/) which would fail without your patch
  • You've added a new changelog entry (in CHANGES.rst).

If this is a trivial change, like a typo fix or a code reformatting, then you can ignore
these instructions.

Updating the changelog

If there are no entries after the last release, use **UNRELEASED** as the version.
If, say, your patch fixes issue #123, the entry should look like this:

- Fix big bad boo-boo in task groups
  (`#123 <https://github.com/agronholm/sqlacodegen/issues/123>`_; PR by @yourgithubaccount)

If there's no issue linked, just link to your pull request instead by updating the
changelog after you've created the PR.

jaogoy and others added 3 commits November 17, 2025 11:20
…alect-types option

### Summary
- Render `Table`/`Column` dialect-specific kwargs and `info` in
generated code.
- Add `keep-dialect-types` generator option to preserve dialect-specific
column types instead of adapting to generic SQLAlchemy types.

### Motivation
- Some dialect features (e.g., engine/storage params, partitioning,
materialized view metadata) are carried in SQLAlchemy `dialect_kwargs`
or `info` but weren’t emitted by sqlacodegen.
- For custom dialects with their own Column types, the current type
“adaptation” step collapses them into generic SQLAlchemy types, losing
fidelity.

### What’s changed
- Render dialect kwargs and info
- Table (Core): include table-level `dialect_kwargs` and `info` in
`Table(...)` kwargs.
- Column (Core/ORM): include column-level `dialect_kwargs` and `info`
in `Column(...)` / `mapped_column(...)`.
- Declarative: include table-level `dialect_kwargs` and `info` in
`__table_args__` dict.
- New option: keep-dialect-types
  - Generator option: `keep_dialect_types`.
  - CLI flag: `--options=keep_dialect_types`.
- Behavior: gates only the type adaptation step in
`fix_column_types()`; Boolean/Enum inference and PostgreSQL sequence
handling remain intact.

### Usage examples

- Core (Table)

```python
t_orders = Table(
    'orders',
    metadata,
    Column('id', INTEGER, primary_key=True, starrocks_aggr_type='SUM'),
    schema='public',
    comment='orders table',

    info={'table_kind': 'view'}
)
```

- Declarative (`__table_args__`)

```python
class Orders(Base):
    __tablename__ = 'orders'
    __table_args__ = (
        {
            'schema': 'public',
            'comment': 'orders table',
            'info': {'table_kind': 'view'},
	    'starrocks_properties': {'replication_num': '1'},
        }
    )
id: Mapped[INTEGER] = mapped_column(primary_key=True,
starrocks_aggr_type='SUM')
```

- Preserve dialect types

```bash
sqlacodegen postgresql://... --options=keep_dialect_types
```

When the flag is set, dialect-specific types (e.g.,
`starrocks.datatype.INTEGER`) are preserved and imported from their
original module rather than adapted to generic SQLAlchemy types.

### Backward compatibility
- Default behavior is unchanged:
- If `keep_dialect_types` is not set, type adaptation continues as
before.
- Output remains stable except that existing `info`/`dialect_kwargs`
now render when present (additive enhancement).
- No breaking API changes.

Signed-off-by: jaogoy <[email protected]>
### Summary
- Render `Table`/`Column` dialect-specific kwargs and `info` in
generated code.
- Add `include-dialect-options` and `keep-dialect-types` option to
render dialect options and preserve dialect-specific
column types instead of adapting to generic SQLAlchemy types.

### Motivation
- Some dialect features (e.g., engine/storage params, partitioning,
materialized view metadata) are carried in SQLAlchemy `dialect_kwargs`
or `info` but weren’t emitted by sqlacodegen.
- For custom dialects with their own Column types, the current type
“adaptation” step collapses them into generic SQLAlchemy types, losing
fidelity.

### What’s changed
- Render dialect kwargs and info
- Table (Core): include table-level `dialect_kwargs` and `info` in
`Table(...)` kwargs.
- Column (Core/ORM): include column-level `dialect_kwargs` and `info`
in `Column(...)` / `mapped_column(...)`.
- Declarative: include table-level `dialect_kwargs` and `info` in
`__table_args__` dict.
- New option: include-dialect-options, keep-dialect-types
- Behavior: gates only the type adaptation step in
`fix_column_types()`; Boolean/Enum inference and PostgreSQL sequence
handling remain intact.

### Usage examples

- Core (Table)

```python
t_orders = Table(
    'orders',
    metadata,
    Column('id', INTEGER, primary_key=True, starrocks_aggr_type='SUM'),
    schema='public',
    comment='orders table',

    info={'table_kind': 'view'}
)
```

- Declarative (`__table_args__`)

```python
class Orders(Base):
    __tablename__ = 'orders'
    __table_args__ = (
        {
            'schema': 'public',
            'comment': 'orders table',
            'info': {'table_kind': 'view'},
            'starrocks_properties': {'replication_num': '1'},
        }
    )
id: Mapped[INTEGER] = mapped_column(primary_key=True,
starrocks_aggr_type='SUM')
```

- Preserve dialect types

```bash
sqlacodegen postgresql://...
--options=include-dialect-options,keep-dialect-types
```

When the `include-dialect-options` flag is set, it will render the
dialect options (e.g. `starrocks_properties`) and `info` dict (which
will store the `table_kind`, to indicate it's a table or a view/mv, and
the `definition` for a view/mv).
When the `keep-dialect-types` flag is set, dialect-specific types (e.g.,
`starrocks.datatype.INTEGER`) are preserved and imported from their
original module rather than adapted to generic SQLAlchemy types.

### Backward compatibility
- Default behavior is unchanged:
- If `include-dialect-options` is not set, type dialect options and info
will not be rendered as before.
- If `keep-dialect-types` is not set, type adaptation continues as
before.
- No breaking API changes.

Signed-off-by: jaogoy <[email protected]>
@sheinbergon
Copy link
Collaborator

sheinbergon commented Nov 17, 2025

@jaogoy Thank you for your contribution.

Could you please:

  • Update the README.md to reflect new options
  • Update CHANGES.rst to include new option documentation.
  • Add tests for custom dialect options and types to make sure we don not regress in the future

Then we can move forward with the code review

@coveralls
Copy link

Coverage Status

coverage: 96.04% (-1.6%) from 97.64%
when pulling 30fc6c0 on jaogoy:feat.support_dialect
into d7a6024 on agronholm:master.

@coveralls
Copy link

coveralls commented Nov 17, 2025

Coverage Status

coverage: 97.365% (-0.3%) from 97.64%
when pulling ef7b9bf on jaogoy:feat.support_dialect
into d7a6024 on agronholm:master.

@sheinbergon
Copy link
Collaborator

@agronholm a drop of %1.6 in coverage should fail this PR. Why could you verify the coveralls configuration?

@jaogoy
Copy link
Author

jaogoy commented Nov 19, 2025

@sheinbergon Please have a review when you are free.

@sheinbergon
Copy link
Collaborator

So, include-dialect-options seems like a very welcomed addition. Can you explain what's the issue to with keeping the dialect types? what sort of information are you using when doing that? is that related to include-dialect-options (with starrocks, for example)?

@jaogoy
Copy link
Author

jaogoy commented Nov 20, 2025

So, include-dialect-options seems like a very welcomed addition. Can you explain what's the issue to with keeping the dialect types? what sort of information are you using when doing that? is that related to include-dialect-options (with starrocks, for example)?
@sheinbergon

  1. Yes, include-dialect-options is a must for any dialect with any dialect options.
  2. Without keep-dialect-types, sqlacodegen will render sqlatype.Integer for dialect's INTEGER if it inherits the sqlatype.Integer (for example). Then, when using Alembic (a Schema Migration Tool), it will compare the table schema in database and the table scheme defined in the metadata python file, which will be probably generated by using sqlacodegen for the initial stage, and modified by users manually to add or change some tables. If users write the metadta script with dialect's types (such as INTEGER), then Alembic will recoganize that there are differenct (one is sqlatype.Integer, and the other is dialect.INTEGER), it will generate an alter_table(...) operations, what is not expected by users. So, with keep-dialect-types, sqlacodegen will render the dialect's types (such as dialect.INTEGER), then Alembic won't generate unnecessary altering operations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants