@@ -60,6 +60,22 @@ def test_pandas_to_spark_schema_nullable(self):
6060 schema = _pandas_to_spark_schema (df , nullable = False )
6161 assert not schema .fields [0 ].nullable
6262
63+ def test_pandas_to_spark_schema_lowercases_columns (self ):
64+ """Column names from the API are lowercased to match Data Cloud."""
65+ df = pd .DataFrame ({"UnitPrice__c" : [1.0 ], "Quantity__c" : [2 ], "Name__c" : ["a" ]})
66+ schema = _pandas_to_spark_schema (df )
67+ assert [f .name for f in schema .fields ] == [
68+ "unitprice__c" ,
69+ "quantity__c" ,
70+ "name__c" ,
71+ ]
72+
73+ def test_pandas_to_spark_schema_already_lowercase_is_idempotent (self ):
74+ """Already-lowercase column names are returned unchanged."""
75+ df = pd .DataFrame ({"unitprice__c" : [1.0 ], "quantity__c" : [2 ]})
76+ schema = _pandas_to_spark_schema (df )
77+ assert [f .name for f in schema .fields ] == ["unitprice__c" , "quantity__c" ]
78+
6379 def test_pandas_to_spark_schema_datetime_types (self ):
6480 """Test conversion of pandas datetime types to Spark TimestampType."""
6581
@@ -147,8 +163,8 @@ def mock_spark_session(self):
147163
148164 @pytest .fixture
149165 def mock_pandas_dataframe (self ):
150- """Create a sample pandas DataFrame for testing ."""
151- return pd .DataFrame ({"col1 " : [1 , 2 ], "col2 " : ["a" , "b" ]})
166+ """Sample pandas DataFrame with PascalCase columns, as the QueryAPI returns ."""
167+ return pd .DataFrame ({"Col1__c " : [1 , 2 ], "Col2__c " : ["a" , "b" ]})
152168
153169 @pytest .fixture
154170 def mock_connection (self , mock_pandas_dataframe ):
@@ -301,3 +317,27 @@ def test_read_dmo_with_custom_row_limit(
301317 mock_connection .get_pandas_dataframe .assert_called_once_with (
302318 SQL_QUERY_TEMPLATE .format ("test_dmo" , 25 )
303319 )
320+
321+ def test_read_dlo_schema_is_lowercase (
322+ self , reader_without_init , mock_connection , mock_pandas_dataframe
323+ ):
324+ """read_dlo returns a schema with all-lowercase field names even when the
325+ QueryAPI returns PascalCase column names."""
326+ reader_without_init ._conn = mock_connection
327+
328+ reader_without_init .read_dlo ("test_dlo" )
329+
330+ _ , schema_arg = reader_without_init .spark .createDataFrame .call_args [0 ]
331+ assert all (f .name == f .name .lower () for f in schema_arg .fields )
332+
333+ def test_read_dmo_schema_is_lowercase (
334+ self , reader_without_init , mock_connection , mock_pandas_dataframe
335+ ):
336+ """read_dmo returns a schema with all-lowercase field names even when the
337+ QueryAPI returns PascalCase column names."""
338+ reader_without_init ._conn = mock_connection
339+
340+ reader_without_init .read_dmo ("test_dmo" )
341+
342+ _ , schema_arg = reader_without_init .spark .createDataFrame .call_args [0 ]
343+ assert all (f .name == f .name .lower () for f in schema_arg .fields )
0 commit comments