mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-17 22:22:13 -04:00
Add reflection support for Postgresql partitioned tables
Added rudimental support for reflection of Postgresql partitioned tables, e.g. that relkind='p' is added to reflection queries that return table information. Fixes: #4237 Change-Id: I66fd10b002e4ed21ea13b13a7e35a85f66bdea75
This commit is contained in:
Vendored
+36
@@ -409,6 +409,42 @@ Key Behavioral Changes - Core
|
||||
Dialect Improvements and Changes - PostgreSQL
|
||||
=============================================
|
||||
|
||||
.. _change_4237:
|
||||
|
||||
Added basic reflection support for Postgresql paritioned tables
|
||||
---------------------------------------------------------------
|
||||
|
||||
SQLAlchemy can render the "PARTITION BY" sequnce within a Postgresql
|
||||
CREATE TABLE statement using the flag ``postgresql_partition_by``, added in
|
||||
version 1.2.6. However, the ``'p'`` type was not part of the reflection
|
||||
queries used until now.
|
||||
|
||||
Given a schema such as::
|
||||
|
||||
dv = Table(
|
||||
'data_values', metadata,
|
||||
Column('modulus', Integer, nullable=False),
|
||||
Column('data', String(30)),
|
||||
postgresql_partition_by='range(modulus)')
|
||||
|
||||
sa.event.listen(
|
||||
dv,
|
||||
"after_create",
|
||||
sa.DDL(
|
||||
"CREATE TABLE data_values_4_10 PARTITION OF data_values "
|
||||
"FOR VALUES FROM (4) TO (10)")
|
||||
)
|
||||
|
||||
The two table names ``'data_values'`` and ``'data_values_4_10'`` will come
|
||||
back from :meth:`.Inspector.get_table_names` and additionally the columns
|
||||
will come back from ``Inspector.get_columns('data_values')`` as well
|
||||
as ``Inspector.get_columns('data_values_4_10')``. This also extends to the
|
||||
use of ``Table(..., autoload=True)`` with these tables.
|
||||
|
||||
|
||||
:ticket:`4237`
|
||||
|
||||
|
||||
Dialect Improvements and Changes - MySQL
|
||||
=============================================
|
||||
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
.. change::
|
||||
:tags: feature, postgresql
|
||||
:tickets: 4237
|
||||
|
||||
Added rudimental support for reflection of Postgresql
|
||||
partitioned tables, e.g. that relkind='p' is added to reflection
|
||||
queries that return table information.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`change_4237`
|
||||
@@ -2460,7 +2460,8 @@ class PGDialect(default.DefaultDialect):
|
||||
FROM pg_catalog.pg_class c
|
||||
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
||||
WHERE (%s)
|
||||
AND c.relname = :table_name AND c.relkind in ('r', 'v', 'm', 'f')
|
||||
AND c.relname = :table_name AND c.relkind in
|
||||
('r', 'v', 'm', 'f', 'p')
|
||||
""" % schema_where_clause
|
||||
# Since we're binding to unicode, table_name and schema_name must be
|
||||
# unicode.
|
||||
@@ -2491,7 +2492,7 @@ class PGDialect(default.DefaultDialect):
|
||||
result = connection.execute(
|
||||
sql.text("SELECT c.relname FROM pg_class c "
|
||||
"JOIN pg_namespace n ON n.oid = c.relnamespace "
|
||||
"WHERE n.nspname = :schema AND c.relkind = 'r'"
|
||||
"WHERE n.nspname = :schema AND c.relkind in ('r', 'p')"
|
||||
).columns(relname=sqltypes.Unicode),
|
||||
schema=schema if schema is not None else self.default_schema_name)
|
||||
return [name for name, in result]
|
||||
|
||||
@@ -74,6 +74,51 @@ class ForeignTableReflectionTest(fixtures.TablesTest, AssertsExecutionResults):
|
||||
eq_(names, ['testtable'])
|
||||
|
||||
|
||||
class PartitionedReflectionTest(
|
||||
fixtures.TablesTest, AssertsExecutionResults):
|
||||
# partitioned table reflection, issue #4237
|
||||
|
||||
__only_on__ = 'postgresql >= 10'
|
||||
__backend__ = True
|
||||
|
||||
@classmethod
|
||||
def define_tables(cls, metadata):
|
||||
# the actual function isn't reflected yet
|
||||
dv = Table(
|
||||
'data_values', metadata,
|
||||
Column('modulus', Integer, nullable=False),
|
||||
Column('data', String(30)),
|
||||
postgresql_partition_by='range(modulus)')
|
||||
|
||||
# looks like this is reflected prior to #4237
|
||||
sa.event.listen(
|
||||
dv,
|
||||
"after_create",
|
||||
sa.DDL(
|
||||
"CREATE TABLE data_values_4_10 PARTITION OF data_values "
|
||||
"FOR VALUES FROM (4) TO (10)")
|
||||
)
|
||||
|
||||
def test_get_tablenames(self):
|
||||
assert {'data_values', 'data_values_4_10'}.issubset(
|
||||
inspect(testing.db).get_table_names()
|
||||
)
|
||||
|
||||
def test_reflect_cols(self):
|
||||
cols = inspect(testing.db).get_columns('data_values')
|
||||
eq_(
|
||||
[c['name'] for c in cols],
|
||||
['modulus', 'data']
|
||||
)
|
||||
|
||||
def test_reflect_cols_from_partition(self):
|
||||
cols = inspect(testing.db).get_columns('data_values_4_10')
|
||||
eq_(
|
||||
[c['name'] for c in cols],
|
||||
['modulus', 'data']
|
||||
)
|
||||
|
||||
|
||||
class MaterializedViewReflectionTest(
|
||||
fixtures.TablesTest, AssertsExecutionResults):
|
||||
"""Test reflection on materialized views"""
|
||||
|
||||
Reference in New Issue
Block a user