Skip to content

Conversation

danplischke
Copy link

@danplischke danplischke commented Aug 19, 2025

Changes

Fixes #423, #392

Added custom handling for Postgres TSVECTOR type, as python_type is not implemented in sqlalchemy type.
Also added metadataref for SQLModel generation, which would lead to syntax errors for fallback SQLAlchemy Tables.

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.

@agronholm
Copy link
Owner

Wouldn't it be a lot better to just send a PR to upstream to implement python_type?

@coveralls
Copy link

coveralls commented Aug 19, 2025

Coverage Status

coverage: 97.707% (+0.04%) from 97.671%
when pulling 6c79daa on danplischke:master
into f41d8b4 on agronholm:master.

@sheinbergon
Copy link
Collaborator

Can you elaborate on adding SQLModel.metadata?

@danplischke
Copy link
Author

danplischke commented Aug 19, 2025

SQLModel.metadata

Sure! For tables that don't have a primary key, we fall back to using SQLAlchemy Models, however due to the missing metadataref we get this:

test_table = Table(
    'test_table', ,
    Column('test', Integer),
    schema='test'
)

which is missing the metadata parameter which is mandatory in SQLAlchemy.
Assuming that users want to work with SQLModel when they use the SQLModel generator, this fixes the syntax error and allows users to work with SQLModel.metadata e.g. to (create_all)[https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/?h=create#calling-create_all].

@danplischke
Copy link
Author

danplischke commented Aug 19, 2025

Wouldn't it be a lot better to just send a PR to upstream to implement python_type?

Sure, happy to open a PR there.
Just a thought, would it make sense to fall back to typing.Any if python_type is not implemented and log a warning?
Only to be able to use this package without errors for special types.

@agronholm
Copy link
Owner

Wouldn't it be a lot better to just send a PR to upstream to implement python_type?

Sure, happy to open a PR there. Just a thought, would it make sense to fall back to typing.Any if python_type is not implemented and log a warning? Only to be able to use this package without errors for special types.

Yes, we are planning to catch the NotImplementedError and using typing.Any in that case.

@agronholm
Copy link
Owner

Assuming that users want to work with SQLModel when they use the SQLModel generator, this fixes the syntax error and allows users to work with SQLModel.metadata e.g. to (create_all)[https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/?h=create#calling-create_all].

@sheinbergon I think we might prefer this approach instead of just not generating any code for such tables.

@sheinbergon
Copy link
Collaborator

Assuming that users want to work with SQLModel when they use the SQLModel generator, this fixes the syntax error and allows users to work with SQLModel.metadata e.g. to (create_all)[https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/?h=create#calling-create_all].

@sheinbergon I think we might prefer this approach instead of just not generating any code for such tables.

@agronholm Just what I had in mind

@danplischke danplischke changed the title fix: handle python type for Postgres TSVECTOR handle SQLAlchemy types with unimplemented python_type as typing.Any & use SQLModel.metadata as metadataref Aug 19, 2025
@danplischke
Copy link
Author

danplischke commented Aug 19, 2025

Wouldn't it be a lot better to just send a PR to upstream to implement python_type?

Sure, happy to open a PR there. Just a thought, would it make sense to fall back to typing.Any if python_type is not implemented and log a warning? Only to be able to use this package without errors for special types.

Yes, we are planning to catch the NotImplementedError and using typing.Any in that case.

So, like this? (changed the code in this PR)

@sheinbergon
Copy link
Collaborator

Wouldn't it be a lot better to just send a PR to upstream to implement python_type?

Sure, happy to open a PR there. Just a thought, would it make sense to fall back to typing.Any if python_type is not implemented and log a warning? Only to be able to use this package without errors for special types.

Yes, we are planning to catch the NotImplementedError and using typing.Any in that case.

So, like this? (changed the code in this PR)

I think so, I will give a more thorough look later on today. @danplischke your contribution is much appreciated

Copy link
Collaborator

@sheinbergon sheinbergon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments

try:
python_type = column_type.python_type
except NotImplementedError:
_logger.warning(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this warning, we'll be encountering this left and right for any non-standard use case

python_type_name = (
python_type.__name__
if hasattr(python_type, "__name__")
else python_type._name
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the deal with this fallback? we can we expect for python_type._name to succeed

@@ -1435,7 +1449,7 @@ def generate_base(self) -> None:
self.base = Base(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test to cover this behavior for SQLModels?

@sheinbergon sheinbergon added this to the 3.1.x milestone Aug 19, 2025
@sheinbergon
Copy link
Collaborator

Assuming that users want to work with SQLModel when they use the SQLModel generator, this fixes the syntax error and allows users to work with SQLModel.metadata e.g. to (create_all)[https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/?h=create#calling-create_all].

While this PR provides a nice behavior for SQLModels, we need to think about other generators

python_type_name = (
python_type.__name__
if hasattr(python_type, "__name__")
else python_type._name
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just to accommodate Any?

Copy link
Author

@danplischke danplischke Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, unfortunately and only in 3.9 as Any is a _SpecialForm type that is missing name

@danplischke danplischke marked this pull request as draft August 20, 2025 09:52
@sheinbergon
Copy link
Collaborator

@danplischke this contribution is important to us. While you can try and tackle both issues covered in the same PR, though I suggest we split it into 2 parts:

  • python_type NotImplemeted error recovery, which is a critical fix (I was aiming to tackle it myself in a day or so)
  • SQLModel.metadata PK-less table fallback fixes.

If you require assistance, or want to split the work, let me know

@sheinbergon
Copy link
Collaborator

@danplischke hi. I've ported (and modified) your work to fix the NotImplemetned error regression introduced in 3.1.0 to #428, now a released in 3.1.1 (you were credited).

If you still want to work on SQLModel fixes, please rework your PR to reflect that.

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.

Possible issue with 3.1.0 and sqlacodegen[geoalchemy2]
4 participants