From 54c1a290a42cc34dac5879ff99aa3e308c48caf4 Mon Sep 17 00:00:00 2001 From: Roel Arents Date: Mon, 18 Nov 2024 14:24:52 +0100 Subject: [PATCH] perform foreign key violations check on whole gpkg at once PDOK-16629 --- .../validations/table_definitions_check.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/geopackage_validator/validations/table_definitions_check.py b/geopackage_validator/validations/table_definitions_check.py index 37e5dcd..e925bf9 100644 --- a/geopackage_validator/validations/table_definitions_check.py +++ b/geopackage_validator/validations/table_definitions_check.py @@ -135,14 +135,18 @@ def compare_table_definitions( return results -def check_foreign_keys(datasource: DataSource, table_name: str) -> List[str]: +def get_foreign_key_violations(datasource: DataSource) -> List[str]: + # This used to be a per-table operation. But it's not due to + # a bug in sqlite: https://sqlite.org/forum/info/30cd7db3d0b2f12e + # used in github ubuntu 20-04: + # https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2004-Readme.md#installed-apt-packages messages: List[str] = [] foreign_key_violations = datasource.ExecuteSQL( - f"select rowid, parent, fkid from pragma_foreign_key_check('{table_name}');" + f"select \"table\", rowid, parent, fkid from pragma_foreign_key_check();" ) - for violation in foreign_key_violations: + for v in foreign_key_violations: messages.append( - f"foreign key violation in {table_name} for fk {violation['fkid']} to {violation['parent']} on row {violation['rowid']}" + f"foreign key violation in {v['table']} for fk {v['fkid']} to {v['parent']} on row {v['rowid']}" ) return messages @@ -185,8 +189,7 @@ def check_foreign_keys(self) -> List[str]: for table_definition in self.table_definitions.tables: if table_definition.foreign_keys is None: messages += f"foreign keys checking is enabled but {table_definition.name} misses the list" - elif len(table_definition.foreign_keys) > 0: - messages += check_foreign_keys(self.dataset, table_definition.name) + messages += get_foreign_key_violations(self.dataset) return messages