Skip to content

Commit df6977d

Browse files
martinv13claude
andauthored
Fix KeyError when xs:choice branches share an element with same name and type (#60)
* Fix KeyError when xs:choice branches share an element with same name and type In add_relation_1/add_relation_n, skip duplicate relations where a field with the same name and same XSD type already exists. Previously, self.fields (a list) accumulated both occurrences while self.relations_1/n (dicts) only kept the last, causing a KeyError in simplify_table when the first occurrence was elevated and the second tried to look it up. Add deliveryType to the orders crash-test schema to cover this case, with order3.xml exercising both the sequence branch (from+to) and standalone branch (to). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Bump version from 0.13.1 to 0.13.2 --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 64509b3 commit df6977d

22 files changed

Lines changed: 303 additions & 16 deletions

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "xml2db"
7-
version = "0.13.1"
7+
version = "0.13.2"
88
authors = [
99
{ name="Commission de régulation de l'énergie", email="opensource@cre.fr" },
1010
]

src/xml2db/table/table.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ def add_relation_1(
180180
raise ValueError(
181181
"attempting to add a 1-1 relationship with max occurrences different from 1"
182182
)
183+
if (
184+
name in self.relations_1
185+
and self.relations_1[name].other_table.type_name == other_table.type_name
186+
):
187+
return
183188
rel = DataModelRelation1(
184189
name,
185190
[(name, other_table.type_name)],
@@ -206,6 +211,11 @@ def add_relation_n(self, name, other_table, occurs, ngroup):
206211
raise ValueError(
207212
"attempting to add a 1-n relationship with max occurrences equal to 1"
208213
)
214+
if (
215+
name in self.relations_n
216+
and self.relations_n[name].other_table.type_name == other_table.type_name
217+
):
218+
return
209219
rel = DataModelRelationN(
210220
name,
211221
[(name, other_table.type_name)],

tests/sample_models/orders/orders.xsd

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,26 @@
7171
</xs:sequence>
7272
</xs:complexType>
7373

74+
<!-- deliveryType tests the case where the same element name and complex type appear
75+
in two branches of a xs:choice (sequence branch and standalone branch) -->
76+
<xs:complexType name="deliveryType">
77+
<xs:choice>
78+
<xs:sequence>
79+
<xs:element name="from" type="contacttype"/>
80+
<xs:element name="to" type="contacttype"/>
81+
</xs:sequence>
82+
<xs:element name="to" type="contacttype"/>
83+
</xs:choice>
84+
</xs:complexType>
85+
7486
<xs:complexType name="itemtype">
7587
<xs:sequence>
7688
<xs:element name="product" type="producttype" minOccurs="1" maxOccurs="1"/>
7789
<xs:element name="note" type="bt:stringtype" minOccurs="0"/>
7890
<xs:element name="quantity" type="bt:quantitytype"/>
7991
<xs:element name="price" type="bt:dectype"/>
8092
<xs:element name="currency" type="bt:currencytype"/>
93+
<xs:element name="delivery" type="deliveryType" minOccurs="0" maxOccurs="1"/>
8194
</xs:sequence>
8295
</xs:complexType>
8396

tests/sample_models/orders/orders_ddl_mssql_version0.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ CREATE TABLE item (
4848
quantity INTEGER NULL,
4949
price DOUBLE PRECISION NULL,
5050
currency CHAR(3) NULL,
51+
delivery_from_fk_orderperson INTEGER NULL,
52+
delivery_to_fk_orderperson INTEGER NULL,
5153
record_hash BINARY(20) NULL,
5254
CONSTRAINT cx_pk_item PRIMARY KEY CLUSTERED (pk_item),
53-
CONSTRAINT item_xml2db_record_hash UNIQUE (record_hash)
55+
CONSTRAINT item_xml2db_record_hash UNIQUE (record_hash),
56+
FOREIGN KEY(delivery_from_fk_orderperson) REFERENCES orderperson (pk_orderperson),
57+
FOREIGN KEY(delivery_to_fk_orderperson) REFERENCES orderperson (pk_orderperson)
5458
)
5559

5660

tests/sample_models/orders/orders_ddl_mssql_version1.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,12 @@ CREATE TABLE item (
8787
quantity INTEGER NULL,
8888
price DOUBLE PRECISION NULL,
8989
currency CHAR(3) NULL,
90+
delivery_from_fk_orderperson INTEGER NULL,
91+
delivery_to_fk_orderperson INTEGER NULL,
9092
CONSTRAINT cx_pk_item PRIMARY KEY CLUSTERED (pk_item),
91-
FOREIGN KEY(fk_parent_shiporder) REFERENCES shiporder (pk_shiporder)
93+
FOREIGN KEY(fk_parent_shiporder) REFERENCES shiporder (pk_shiporder),
94+
FOREIGN KEY(delivery_from_fk_orderperson) REFERENCES orderperson (pk_orderperson),
95+
FOREIGN KEY(delivery_to_fk_orderperson) REFERENCES orderperson (pk_orderperson)
9296
)
9397

9498

tests/sample_models/orders/orders_ddl_mssql_version2.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,14 @@ CREATE TABLE item (
8484
quantity INTEGER NULL,
8585
price DOUBLE PRECISION NULL,
8686
currency CHAR(3) NULL,
87+
delivery_from_fk_orderperson INTEGER NULL,
88+
delivery_to_fk_orderperson INTEGER NULL,
8789
xml2db_record_hash BINARY(20) NULL,
8890
CONSTRAINT cx_pk_item PRIMARY KEY CLUSTERED (pk_item),
8991
CONSTRAINT item_xml2db_record_hash UNIQUE (xml2db_record_hash),
90-
FOREIGN KEY(fk_product) REFERENCES product (pk_product)
92+
FOREIGN KEY(fk_product) REFERENCES product (pk_product),
93+
FOREIGN KEY(delivery_from_fk_orderperson) REFERENCES orderperson (pk_orderperson),
94+
FOREIGN KEY(delivery_to_fk_orderperson) REFERENCES orderperson (pk_orderperson)
9195
)
9296

9397

tests/sample_models/orders/orders_ddl_mysql_version0.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ CREATE TABLE item (
4848
quantity INTEGER,
4949
price DOUBLE,
5050
currency VARCHAR(3),
51+
delivery_from_fk_orderperson INTEGER,
52+
delivery_to_fk_orderperson INTEGER,
5153
record_hash BINARY(20),
5254
CONSTRAINT cx_pk_item PRIMARY KEY (pk_item),
53-
CONSTRAINT item_xml2db_record_hash UNIQUE (record_hash)
55+
CONSTRAINT item_xml2db_record_hash UNIQUE (record_hash),
56+
FOREIGN KEY(delivery_from_fk_orderperson) REFERENCES orderperson (pk_orderperson),
57+
FOREIGN KEY(delivery_to_fk_orderperson) REFERENCES orderperson (pk_orderperson)
5458
)
5559

5660

tests/sample_models/orders/orders_ddl_mysql_version1.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,12 @@ CREATE TABLE item (
8787
quantity INTEGER,
8888
price DOUBLE,
8989
currency VARCHAR(3),
90+
delivery_from_fk_orderperson INTEGER,
91+
delivery_to_fk_orderperson INTEGER,
9092
CONSTRAINT cx_pk_item PRIMARY KEY (pk_item),
91-
FOREIGN KEY(fk_parent_shiporder) REFERENCES shiporder (pk_shiporder)
93+
FOREIGN KEY(fk_parent_shiporder) REFERENCES shiporder (pk_shiporder),
94+
FOREIGN KEY(delivery_from_fk_orderperson) REFERENCES orderperson (pk_orderperson),
95+
FOREIGN KEY(delivery_to_fk_orderperson) REFERENCES orderperson (pk_orderperson)
9296
)
9397

9498

tests/sample_models/orders/orders_ddl_mysql_version2.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,14 @@ CREATE TABLE item (
8484
quantity INTEGER,
8585
price DOUBLE,
8686
currency VARCHAR(3),
87+
delivery_from_fk_orderperson INTEGER,
88+
delivery_to_fk_orderperson INTEGER,
8789
xml2db_record_hash BINARY(20),
8890
CONSTRAINT cx_pk_item PRIMARY KEY (pk_item),
8991
CONSTRAINT item_xml2db_record_hash UNIQUE (xml2db_record_hash),
90-
FOREIGN KEY(fk_product) REFERENCES product (pk_product)
92+
FOREIGN KEY(fk_product) REFERENCES product (pk_product),
93+
FOREIGN KEY(delivery_from_fk_orderperson) REFERENCES orderperson (pk_orderperson),
94+
FOREIGN KEY(delivery_to_fk_orderperson) REFERENCES orderperson (pk_orderperson)
9195
)
9296

9397

tests/sample_models/orders/orders_ddl_postgresql_version0.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ CREATE TABLE item (
4848
quantity INTEGER,
4949
price DOUBLE PRECISION,
5050
currency VARCHAR(3),
51+
delivery_from_fk_orderperson INTEGER,
52+
delivery_to_fk_orderperson INTEGER,
5153
record_hash BYTEA,
5254
CONSTRAINT cx_pk_item PRIMARY KEY (pk_item),
53-
CONSTRAINT item_xml2db_record_hash UNIQUE (record_hash)
55+
CONSTRAINT item_xml2db_record_hash UNIQUE (record_hash),
56+
FOREIGN KEY(delivery_from_fk_orderperson) REFERENCES orderperson (pk_orderperson),
57+
FOREIGN KEY(delivery_to_fk_orderperson) REFERENCES orderperson (pk_orderperson)
5458
)
5559

5660

0 commit comments

Comments
 (0)