You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2025/07/28 17:59:17 UTC
(superset) branch read-col-metadata created (now cdf2ee82d8)
This is an automated email from the ASF dual-hosted git repository.
beto pushed a change to branch read-col-metadata
in repository https://gitbox.apache.org/repos/asf/superset.git
at cdf2ee82d8 Add tests
This branch includes the following new commits:
new c1fe07264d feat: read column metadata
new cdf2ee82d8 Add tests
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(superset) 01/02: feat: read column metadata
Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
beto pushed a commit to branch read-col-metadata
in repository https://gitbox.apache.org/repos/asf/superset.git
commit c1fe07264d847d4948679c7a2940aa68385b3f33
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Mon Jul 28 12:55:27 2025 -0400
feat: read column metadata
---
superset/connectors/sqla/models.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py
index 5bbafda72d..13a61dbb0f 100644
--- a/superset/connectors/sqla/models.py
+++ b/superset/connectors/sqla/models.py
@@ -1680,6 +1680,9 @@ class SqlaTable(
table=self,
)
new_column.is_dttm = new_column.is_temporal
+ # Set description from comment field if available
+ if col.get("comment"):
+ new_column.description = col["comment"]
db_engine_spec.alter_new_orm_column(new_column)
else:
new_column = old_column
@@ -1687,6 +1690,9 @@ class SqlaTable(
results.modified.append(col["column_name"])
new_column.type = col["type"]
new_column.expression = ""
+ # Set description from comment field if available
+ if col.get("comment"):
+ new_column.description = col["comment"]
new_column.groupby = True
new_column.filterable = True
columns.append(new_column)
(superset) 02/02: Add tests
Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
beto pushed a commit to branch read-col-metadata
in repository https://gitbox.apache.org/repos/asf/superset.git
commit cdf2ee82d8ac8ec5d733eedf72dafe8f06e28000
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Mon Jul 28 13:59:05 2025 -0400
Add tests
---
.../pythonpath_dev/superset_config_docker_light.py | 1 +
tests/integration_tests/sqla_models_tests.py | 242 +++++++++++++++++++++
2 files changed, 243 insertions(+)
diff --git a/docker/pythonpath_dev/superset_config_docker_light.py b/docker/pythonpath_dev/superset_config_docker_light.py
index 9a5ae0ae67..1f053c2ce3 100644
--- a/docker/pythonpath_dev/superset_config_docker_light.py
+++ b/docker/pythonpath_dev/superset_config_docker_light.py
@@ -19,6 +19,7 @@
# Import all settings from the main config first
from flask_caching.backends.filesystemcache import FileSystemCache
+
from superset_config import * # noqa: F403
# Override caching to use simple in-memory cache instead of Redis
diff --git a/tests/integration_tests/sqla_models_tests.py b/tests/integration_tests/sqla_models_tests.py
index c7b0590712..f1c0454fcb 100644
--- a/tests/integration_tests/sqla_models_tests.py
+++ b/tests/integration_tests/sqla_models_tests.py
@@ -1135,3 +1135,245 @@ def test__temporal_range_operator_in_adhoc_filter(physical_dataset):
)
df = pd.DataFrame(index=[0], data={"col1": 4, "col2": "e"})
assert df.equals(result.df)
+
+ def test_fetch_metadata_with_comment_field_new_columns(self):
+ """Test that fetch_metadata correctly assigns comment field to description
+ for new columns
+ """
+ table = SqlaTable(
+ table_name="test_table_with_comments",
+ database=get_example_database(),
+ )
+
+ # Mock external_metadata to return columns with comment fields
+ mock_columns = [
+ {
+ "column_name": "id",
+ "type": "INTEGER",
+ "comment": "Primary key identifier",
+ },
+ {
+ "column_name": "name",
+ "type": "VARCHAR",
+ "comment": "Full name of the user",
+ },
+ {
+ "column_name": "email",
+ "type": "VARCHAR",
+ "comment": "Email address for contact",
+ },
+ {
+ "column_name": "status",
+ "type": "VARCHAR",
+ # No comment field for this column
+ },
+ ]
+
+ with patch.object(table, "external_metadata", return_value=mock_columns):
+ result = table.fetch_metadata()
+
+ # Check that all columns were added
+ assert len(result.added) == 4
+ assert set(result.added) == {"id", "name", "email", "status"}
+
+ # Check that descriptions were set correctly from comments
+ columns_by_name = {col.column_name: col for col in table.columns}
+
+ assert columns_by_name["id"].description == "Primary key identifier"
+ assert columns_by_name["name"].description == "Full name of the user"
+ assert columns_by_name["email"].description == "Email address for contact"
+ # Column without comment should have None/empty description
+ assert columns_by_name["status"].description is None
+
+ def test_fetch_metadata_with_comment_field_existing_columns(self):
+ """Test that fetch_metadata correctly updates description for existing
+ columns
+ """
+ table = SqlaTable(
+ table_name="test_table_existing",
+ database=get_example_database(),
+ )
+
+ # Create existing columns
+ existing_col1 = TableColumn(
+ column_name="id", type="INTEGER", table=table, description="Old description"
+ )
+ existing_col2 = TableColumn(column_name="name", type="VARCHAR", table=table)
+ table.columns = [existing_col1, existing_col2]
+
+ # Save table to get an ID
+ db.session.add(table)
+ db.session.commit()
+
+ # Mock external_metadata to return updated columns with comments
+ mock_columns = [
+ {
+ "column_name": "id",
+ "type": "INTEGER",
+ "comment": "Updated primary key description",
+ },
+ {
+ "column_name": "name",
+ "type": "VARCHAR",
+ "comment": "Updated name description",
+ },
+ ]
+
+ with patch.object(table, "external_metadata", return_value=mock_columns):
+ result = table.fetch_metadata()
+
+ # No new columns should be added
+ assert len(result.added) == 0
+
+ # Check that descriptions were updated from comments
+ columns_by_name = {col.column_name: col for col in table.columns}
+
+ assert (
+ columns_by_name["id"].description == "Updated primary key description"
+ )
+ assert columns_by_name["name"].description == "Updated name description"
+
+ # Cleanup
+ db.session.delete(table)
+ db.session.commit()
+
+ def test_fetch_metadata_mixed_comment_scenarios(self):
+ """Test fetch_metadata with mix of new/existing columns and with/without
+ comments
+ """
+ table = SqlaTable(
+ table_name="test_table_mixed",
+ database=get_example_database(),
+ )
+
+ # Create one existing column
+ existing_col = TableColumn(
+ column_name="existing_col",
+ type="INTEGER",
+ table=table,
+ description="Existing description",
+ )
+ table.columns = [existing_col]
+
+ # Save table to get an ID
+ db.session.add(table)
+ db.session.commit()
+
+ # Mock external_metadata with mix of scenarios
+ mock_columns = [
+ {
+ "column_name": "existing_col",
+ "type": "INTEGER",
+ "comment": "Updated existing column comment",
+ },
+ {
+ "column_name": "new_with_comment",
+ "type": "VARCHAR",
+ "comment": "New column with comment",
+ },
+ {
+ "column_name": "new_without_comment",
+ "type": "VARCHAR",
+ # No comment field
+ },
+ ]
+
+ with patch.object(table, "external_metadata", return_value=mock_columns):
+ result = table.fetch_metadata()
+
+ # Check added columns
+ assert len(result.added) == 2
+ assert set(result.added) == {"new_with_comment", "new_without_comment"}
+
+ # Check all column descriptions
+ columns_by_name = {col.column_name: col for col in table.columns}
+
+ # Existing column should have updated description
+ assert (
+ columns_by_name["existing_col"].description
+ == "Updated existing column comment"
+ )
+
+ # New column with comment should have description set
+ assert (
+ columns_by_name["new_with_comment"].description
+ == "New column with comment"
+ )
+
+ # New column without comment should have None description
+ assert columns_by_name["new_without_comment"].description is None
+
+ # Cleanup
+ db.session.delete(table)
+ db.session.commit()
+
+ def test_fetch_metadata_no_comment_field_safe_handling(self):
+ """Test that fetch_metadata safely handles columns with no comment field"""
+ table = SqlaTable(
+ table_name="test_table_no_comments",
+ database=get_example_database(),
+ )
+
+ # Mock external_metadata with columns that have no comment fields
+ mock_columns = [
+ {"column_name": "col1", "type": "INTEGER"},
+ {"column_name": "col2", "type": "VARCHAR"},
+ ]
+
+ with patch.object(table, "external_metadata", return_value=mock_columns):
+ # This should not raise any exceptions
+ result = table.fetch_metadata()
+
+ # Check that columns were added successfully
+ assert len(result.added) == 2
+ assert set(result.added) == {"col1", "col2"}
+
+ # Check that descriptions are None (not set)
+ columns_by_name = {col.column_name: col for col in table.columns}
+ assert columns_by_name["col1"].description is None
+ assert columns_by_name["col2"].description is None
+
+ def test_fetch_metadata_empty_comment_field_handling(self):
+ """Test that fetch_metadata handles empty comment fields correctly"""
+ table = SqlaTable(
+ table_name="test_table_empty_comments",
+ database=get_example_database(),
+ )
+
+ # Mock external_metadata with empty comment fields
+ mock_columns = [
+ {
+ "column_name": "col_with_empty_comment",
+ "type": "INTEGER",
+ "comment": "", # Empty string comment
+ },
+ {
+ "column_name": "col_with_none_comment",
+ "type": "VARCHAR",
+ "comment": None, # None comment
+ },
+ {
+ "column_name": "col_with_valid_comment",
+ "type": "VARCHAR",
+ "comment": "Valid comment",
+ },
+ ]
+
+ with patch.object(table, "external_metadata", return_value=mock_columns):
+ result = table.fetch_metadata()
+
+ # Check that all columns were added
+ assert len(result.added) == 3
+
+ columns_by_name = {col.column_name: col for col in table.columns}
+
+ # Empty string comment should not be set (falsy)
+ assert columns_by_name["col_with_empty_comment"].description is None
+
+ # None comment should not be set
+ assert columns_by_name["col_with_none_comment"].description is None
+
+ # Valid comment should be set
+ assert (
+ columns_by_name["col_with_valid_comment"].description == "Valid comment"
+ )