@@ -260,8 +260,10 @@ def set_v2_compatible_defaults(cls, data: Dict[str, Any]) -> Dict[str, Any]:
260260 The TableMetadata with the defaults applied.
261261 """
262262 # When the schema doesn't have an ID
263- if data .get ("schema" ) and "schema_id" not in data ["schema" ]:
264- data ["schema" ]["schema_id" ] = DEFAULT_SCHEMA_ID
263+ schema = data .get ("schema" )
264+ if isinstance (schema , dict ):
265+ if "schema_id" not in schema :
266+ schema ["schema_id" ] = DEFAULT_SCHEMA_ID
265267
266268 return data
267269
@@ -313,6 +315,34 @@ def construct_partition_specs(cls, data: Dict[str, Any]) -> Dict[str, Any]:
313315
314316 return data
315317
318+ @model_validator (mode = "before" )
319+ def construct_v1_spec_from_v2_fields (cls , data : Dict [str , Any ]) -> Dict [str , Any ]:
320+ specs_field = "partition_specs"
321+ default_spec_id_field = "default_spec_id"
322+ if specs_field in data and default_spec_id_field in data :
323+ found_spec = next ((spec for spec in data [specs_field ] if spec .spec_id == data [default_spec_id_field ]), None )
324+ if found_spec is not None :
325+ spec_dict = found_spec .model_dump ()
326+ spec_dict ['fields' ] = list (spec_dict ['fields' ])
327+ data ["partition_spec" ] = [spec_dict ]
328+ return data
329+
330+ return data
331+
332+ @model_validator (mode = "before" )
333+ def construct_v1_schema_from_v2_fields (cls , data : Dict [str , Any ]) -> Dict [str , Any ]:
334+ schemas_field = "schemas"
335+ current_schema_id_field = "current_schema_id"
336+ if schemas_field in data and current_schema_id_field in data :
337+ found_schema = next (
338+ (schema for schema in data [schemas_field ] if schema .schema_id == data [current_schema_id_field ]), None
339+ )
340+ if found_schema is not None :
341+ data ["schema" ] = found_schema
342+ return data
343+
344+ return data
345+
316346 @model_validator (mode = "before" )
317347 def set_sort_orders (cls , data : Dict [str , Any ]) -> Dict [str , Any ]:
318348 """Set the sort_orders if not provided.
@@ -335,7 +365,7 @@ def to_v2(self) -> TableMetadataV2:
335365 metadata ["format-version" ] = 2
336366 return TableMetadataV2 .model_validate (metadata )
337367
338- format_version : Literal [1 ] = Field (alias = "format-version" )
368+ format_version : Literal [1 ] = Field (alias = "format-version" , default = 1 )
339369 """An integer version number for the format. Currently, this can be 1 or 2
340370 based on the spec. Implementations must throw an exception if a table’s
341371 version is higher than the supported version."""
@@ -394,6 +424,7 @@ def construct_refs(cls, table_metadata: TableMetadata) -> TableMetadata:
394424
395425
396426TableMetadata = Annotated [Union [TableMetadataV1 , TableMetadataV2 ], Field (discriminator = "format_version" )]
427+ DEFAULT_FORMAT_VERSION = "2"
397428
398429
399430def new_table_metadata (
@@ -411,6 +442,24 @@ def new_table_metadata(
411442 if table_uuid is None :
412443 table_uuid = uuid .uuid4 ()
413444
445+ # Remove format-version so it does not get persisted
446+ format_version = int (properties .pop ("format-version" , DEFAULT_FORMAT_VERSION ))
447+
448+ if format_version == 1 :
449+ return TableMetadataV1 (
450+ location = location ,
451+ schema = fresh_schema ,
452+ last_column_id = fresh_schema .highest_field_id ,
453+ current_schema_id = fresh_schema .schema_id ,
454+ partition_specs = [fresh_partition_spec ],
455+ default_spec_id = fresh_partition_spec .spec_id ,
456+ sort_orders = [fresh_sort_order ],
457+ default_sort_order_id = fresh_sort_order .order_id ,
458+ properties = properties ,
459+ last_partition_id = fresh_partition_spec .last_assigned_field_id ,
460+ table_uuid = table_uuid ,
461+ )
462+
414463 return TableMetadataV2 (
415464 location = location ,
416465 schemas = [fresh_schema ],
0 commit comments