-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
add reflection for pg DOMAIN types similarly to ENUM reflection #10693
Description
Describe the use case
Motivated by an issue which I initially filed as sqlalchemy/alembic#1357, I did a little more digging into what was actually causing the issue today. It turns out that the column type information for DOMAIN columns is being replaced with a column of the domain's underlying type during reflection (see lib/sqlalchemy/dialects/postgresql/base.py:3760-3773). Note that the coltype isn't being set in that block, instead it replaces the attype and loops until it finds a suitable type to use instead of the domain.
Since it seems that the erasure is intentional (probably to work around deeper issues with wrapped types), I'm hesitant to pursue my investigation without seeking further guidance from someone more familiar with sqlalchemy internals.
Optional link from https://docs.sqlalchemy.org which documents the behavior that is expected
No response
SQLAlchemy Version in Use
2.1.0b1
DBAPI (i.e. the database driver)
psycopg2
Database Vendor and Major Version
PostgreSQL 15.4
Python Version
3.11
Operating system
Ubuntu
To Reproduce
def test_domain_type_reflection(self, metadata, connection):
positive_int = DOMAIN("positive_int", Integer(), check='value > 0', not_null=True)
Table(
"table",
metadata,
Column("value", positive_int)
)
metadata.create_all(connection)
m2 = MetaData()
t2 = Table("table", m2, autoload_with=connection)
eq_(t2.c.value.type.name, 'positive_int')
eq_(t2.c.value.check, 'value > 0')Error
./test/dialect/postgresql/test_types.py::NamedTypeTest::test_domain_type_reflection Failed: [undefined]AttributeError: 'INTEGER' object has no attribute 'name'
Traceback (most recent call last):
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/_pytest/runner.py", line 341, in from_call
result: Optional[TResult] = func()
^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/_pytest/runner.py", line 262, in <lambda>
lambda: ihook(item=item, **kwds), when=when, reraise=reraise
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_hooks.py", line 493, in __call__
return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_manager.py", line 115, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_callers.py", line 152, in _multicall
return outcome.get_result()
^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_result.py", line 114, in get_result
raise exc.with_traceback(exc.__traceback__)
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_callers.py", line 77, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/_pytest/runner.py", line 177, in pytest_runtest_call
raise e
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/_pytest/runner.py", line 169, in pytest_runtest_call
item.runtest()
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/_pytest/python.py", line 1792, in runtest
self.ihook.pytest_pyfunc_call(pyfuncitem=self)
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_hooks.py", line 493, in __call__
return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_manager.py", line 115, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_callers.py", line 113, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/pluggy/_callers.py", line 77, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/.venv/lib/python3.11/site-packages/_pytest/python.py", line 194, in pytest_pyfunc_call
result = testfunction(**testargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ovangle/dev/sqlalchemy/test/dialect/postgresql/test_types.py", line 1109, in test_domain_type_reflection
eq_(t2.c.value.type.name, 'positive_int')
^^^^^^^^^^^^^^^^^^^^
AttributeError: 'INTEGER' object has no attribute 'name'
Additional context
No response