You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by po...@apache.org on 2025/08/22 15:23:04 UTC
(airflow) branch main updated: PostgresDialect should use index instead of name in get_column_names and get_primary_keys (#54832)
This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 2f58d7635eb PostgresDialect should use index instead of name in get_column_names and get_primary_keys (#54832)
2f58d7635eb is described below
commit 2f58d7635eb9d7f75b5f7f4eb7b9c68d214d9ab5
Author: David Blain <in...@dabla.be>
AuthorDate: Fri Aug 22 17:22:57 2025 +0200
PostgresDialect should use index instead of name in get_column_names and get_primary_keys (#54832)
* fix: PostgresDialect should use index instead of name as returned rows are list of tuples, not list of dicts
* refactor: Updated TestPostgresDialect
* Revert "refactor: Updated TestPostgresDialect"
This reverts commit 244b889b49cfdc376080c095024e14d2d2898bdf.
* refactor: Refactored get_column_names in PostgresDialect so it allows back filtering through predicate
* refactor: Also take into account autoincrement columns in PostgresDialect
* refactor: Fixed mocking of records in TestPostgresDialect
* refactor: Reformatted get_column_names
---
.../providers/postgres/dialects/postgres.py | 30 +++++++++++++++++-----
.../tests/unit/postgres/dialects/test_postgres.py | 10 ++++----
2 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/providers/postgres/src/airflow/providers/postgres/dialects/postgres.py b/providers/postgres/src/airflow/providers/postgres/dialects/postgres.py
index 6c1d3104d10..9e31d39b5e8 100644
--- a/providers/postgres/src/airflow/providers/postgres/dialects/postgres.py
+++ b/providers/postgres/src/airflow/providers/postgres/dialects/postgres.py
@@ -42,10 +42,10 @@ class PostgresDialect(Dialect):
if schema is None:
table, schema = self.extract_schema_from_table(table)
pk_columns = [
- row["column_name"]
+ row[0]
for row in self.get_records(
"""
- select kcu.column_name as column_name
+ select kcu.column_name
from information_schema.table_constraints tco
join information_schema.key_column_usage kcu
on kcu.constraint_name = tco.constraint_name
@@ -61,29 +61,45 @@ class PostgresDialect(Dialect):
]
return pk_columns or None
+ @staticmethod
+ def _to_row(row):
+ return {
+ "name": row[0],
+ "type": row[1],
+ "nullable": row[2].casefold() == "yes",
+ "default": row[3],
+ "autoincrement": row[4].casefold() == "always",
+ "identity": row[5].casefold() == "yes",
+ }
+
@lru_cache(maxsize=None)
def get_column_names(
self, table: str, schema: str | None = None, predicate: Callable[[T], bool] = lambda column: True
) -> list[str] | None:
if schema is None:
table, schema = self.extract_schema_from_table(table)
+
column_names = list(
- row["column_name"]
+ row["name"]
for row in filter(
predicate,
- self.get_records(
- """
+ map(
+ self._to_row,
+ self.get_records(
+ """
select column_name,
data_type,
is_nullable,
column_default,
- ordinal_position
+ is_generated,
+ is_identity
from information_schema.columns
where table_schema = %s
and table_name = %s
order by ordinal_position
""",
- (self.unescape_word(schema), self.unescape_word(table)),
+ (self.unescape_word(schema), self.unescape_word(table)),
+ ),
),
)
)
diff --git a/providers/postgres/tests/unit/postgres/dialects/test_postgres.py b/providers/postgres/tests/unit/postgres/dialects/test_postgres.py
index 5406805420b..999386baac1 100644
--- a/providers/postgres/tests/unit/postgres/dialects/test_postgres.py
+++ b/providers/postgres/tests/unit/postgres/dialects/test_postgres.py
@@ -30,12 +30,12 @@ class TestPostgresDialect:
assert "hollywood" in parameters, "Missing 'schema' in parameters"
assert "actors" in parameters, "Missing 'table' in parameters"
if "kcu." in sql:
- return [{"column_name": "id"}]
+ return [("id",)]
return [
- {"column_name": "id", "identity": True},
- {"column_name": "name"},
- {"column_name": "firstname"},
- {"column_name": "age"},
+ ("id", None, "NO", None, "ALWAYS", "YES"),
+ ("name", None, "YES", None, "NEVER", "NO"),
+ ("firstname", None, "YES", None, "NEVER", "NO"),
+ ("age", None, "YES", None, "NEVER", "NO"),
]
self.test_db_hook = MagicMock(placeholder="?", spec=DbApiHook)