@@ -715,6 +715,9 @@ def _logical_to_schema_name(self, logical_name: str) -> str:
715715
716716 Use this ONLY when creating new entities where we control the SchemaName.
717717 For existing entities, use _get_entity_schema_name() to get the actual SchemaName from server.
718+
719+ Note: All callers (_create_table, _create_columns) validate that logical_name contains
720+ an underscore before calling this method, enforcing Dataverse's publisher prefix requirement.
718721 """
719722 # Normalize logical name first
720723 logical_name = self ._normalize_logical_name (logical_name )
@@ -723,10 +726,7 @@ def _logical_to_schema_name(self, logical_name: str) -> str:
723726 if not logical_name :
724727 raise ValueError ("logical_name cannot be empty or whitespace-only" )
725728
726- if "_" not in logical_name :
727- # No prefix, just capitalize first letter
728- return logical_name [:1 ].upper () + logical_name [1 :]
729-
729+ # Split on first underscore to get prefix and name parts
730730 prefix , rest = logical_name .split ("_" , 1 )
731731
732732 # Validate that rest is not empty (e.g., "new_" is invalid)
@@ -764,7 +764,7 @@ def _get_attribute_schema_name(self, entity_logical: str, attribute_logical: str
764764 return self ._attribute_schema_cache [cache_key ]
765765
766766 # Get entity metadata ID first
767- ent = self ._get_entity_by_logical (entity_logical )
767+ ent = self ._get_entity_by_logical_name (entity_logical )
768768 if not ent or not ent .get ("MetadataId" ):
769769 raise MetadataError (
770770 f"Entity '{ entity_logical } ' not found." ,
@@ -829,7 +829,7 @@ def _get_entity_by_schema(
829829 items = r .json ().get ("value" , [])
830830 return items [0 ] if items else None
831831
832- def _get_entity_by_logical (
832+ def _get_entity_by_logical_name (
833833 self ,
834834 logical_name : str ,
835835 headers : Optional [Dict [str , str ]] = None ,
@@ -874,7 +874,7 @@ def _create_entity(
874874 if solution_unique_name :
875875 params = {"SolutionUniqueName" : solution_unique_name }
876876 self ._request ("post" , url , json = payload , params = params )
877- ent = self ._get_entity_by_logical (
877+ ent = self ._get_entity_by_logical_name (
878878 logical_name ,
879879 headers = {"Consistency" : "Strong" },
880880 )
@@ -1280,7 +1280,7 @@ def _get_table_info(self, logical_name: str) -> Optional[Dict[str, Any]]:
12801280 # Normalize logical name for case-insensitive handling
12811281 logical_name = self ._normalize_logical_name (logical_name )
12821282
1283- ent = self ._get_entity_by_logical (logical_name )
1283+ ent = self ._get_entity_by_logical_name (logical_name )
12841284 if not ent :
12851285 return None
12861286 return {
@@ -1305,7 +1305,7 @@ def _delete_table(self, logical_name: str) -> None:
13051305 logical_name = self ._normalize_logical_name (logical_name )
13061306
13071307 # Use strong consistency to ensure we get latest metadata after recent create
1308- ent = self ._get_entity_by_logical (logical_name , headers = {"Consistency" : "Strong" })
1308+ ent = self ._get_entity_by_logical_name (logical_name , headers = {"Consistency" : "Strong" })
13091309 if not ent or not ent .get ("MetadataId" ):
13101310 raise MetadataError (
13111311 f"Table '{ logical_name } ' not found." ,
@@ -1379,7 +1379,7 @@ def _create_columns(
13791379 # Normalize logical name for case-insensitive handling
13801380 logical_name = self ._normalize_logical_name (logical_name )
13811381
1382- ent = self ._get_entity_by_logical (logical_name )
1382+ ent = self ._get_entity_by_logical_name (logical_name )
13831383 if not ent or not ent .get ("MetadataId" ):
13841384 raise MetadataError (
13851385 f"Table '{ logical_name } ' not found." ,
@@ -1393,6 +1393,11 @@ def _create_columns(
13931393 for column_name , column_type in columns .items ():
13941394 # Normalize column logical name for case-insensitive handling
13951395 column_name_normalized = self ._normalize_logical_name (column_name )
1396+
1397+ # Validate that column name includes publisher prefix
1398+ if "_" not in column_name_normalized :
1399+ raise ValueError (f"Column logical name must include publisher prefix (e.g., 'new_columnname'), got: '{ column_name } '" )
1400+
13961401 # Convert column logical name to SchemaName
13971402 col_schema = self ._logical_to_schema_name (column_name_normalized )
13981403 payload = self ._attribute_payload (col_schema , column_type )
@@ -1428,7 +1433,7 @@ def _delete_columns(
14281433 # Normalize logical name for case-insensitive handling
14291434 logical_name = self ._normalize_logical_name (logical_name )
14301435
1431- ent = self ._get_entity_by_logical (logical_name )
1436+ ent = self ._get_entity_by_logical_name (logical_name )
14321437 if not ent or not ent .get ("MetadataId" ):
14331438 raise MetadataError (
14341439 f"Table '{ logical_name } ' not found." ,
0 commit comments