From 749df38b858a79dc4b3f4673c343f0ed12205c21 Mon Sep 17 00:00:00 2001 From: Giovanni Barillari Date: Wed, 24 Jul 2024 13:05:38 +0200 Subject: [PATCH 1/2] Bump version to 2.5.13 --- emmett/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emmett/__version__.py b/emmett/__version__.py index fc78dc7b..177f9a09 100644 --- a/emmett/__version__.py +++ b/emmett/__version__.py @@ -1 +1 @@ -__version__ = "2.5.12" +__version__ = "2.5.13" diff --git a/pyproject.toml b/pyproject.toml index 99cd9379..527c7bb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "emmett" [tool.poetry] name = "emmett" -version = "2.5.12" +version = "2.5.13" description = "The web framework for inventors" authors = ["Giovanni Barillari "] license = "BSD-3-Clause" From 7014464454a7f51d45e0a18c7f1c0160d3adf3fd Mon Sep 17 00:00:00 2001 From: Giovanni Barillari Date: Wed, 24 Jul 2024 13:06:01 +0200 Subject: [PATCH 2/2] Fix FK generation with multi-PK targets and same belongs src (#501) --- emmett/orm/models.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/emmett/orm/models.py b/emmett/orm/models.py index 4e3ecf6f..186612e1 100644 --- a/emmett/orm/models.py +++ b/emmett/orm/models.py @@ -367,12 +367,15 @@ def _define_props_(self): setattr(self.__class__, name, obj) self.fields.append(obj._make_field(name, self)) - def __find_matching_fk_definition(self, fields, rmodel): + def __find_matching_fk_definition(self, rfields, lfields, rmodel): match = None - if not set(fields).issubset(set(rmodel.primary_keys)): + if not set(rfields).issubset(set(rmodel.primary_keys)): return match for key, val in self.foreign_keys.items(): - if set(val["foreign_fields"]) == set(rmodel.primary_keys): + if ( + set(val["foreign_fields"]) == set(rmodel.primary_keys) and + set(lfields).issubset(set(val["fields"])) + ): match = key break return match @@ -410,7 +413,7 @@ def _define_relations_(self): fk_def_key, fks_data, multi_fk = None, {}, [] if ref_multi_pk and reference.fk: fk_def_key = self.__find_matching_fk_definition( - [reference.fk], refmodel + [reference.fk], [reference.name], refmodel ) if not fk_def_key: raise SyntaxError( @@ -546,22 +549,23 @@ def __define_fks(self): ): continue if len(rmodel._fieldset_pk) > 1: - match = self.__find_matching_fk_definition([rel.fk], rmodel) + match = self.__find_matching_fk_definition([rel.fk], [rel.name], rmodel) if not match: raise SyntaxError( f"{self.__class__.__name__}.{rname} relation targets a " "compound primary key table. A matching foreign key " "needs to be defined into `foreign_keys`." ) - trels = grouped_rels[rmodel.tablename] = grouped_rels.get( - rmodel.tablename, { + crels = grouped_rels[match] = grouped_rels.get( + match, { 'rels': {}, + 'table': rmodel.tablename, 'on_delete': self.foreign_keys[match].get( "on_delete", "cascade" ) } ) - trels['rels'][rname] = rel + crels['rels'][rname] = rel else: # NOTE: we need this since pyDAL doesn't support id/refs types != int implicit_defs[rname] = { @@ -575,15 +579,15 @@ def __define_fks(self): rel['table'], *rel['fields_local'] ) self._foreign_keys_[constraint_name] = {**rel} - for tname, rels in grouped_rels.items(): + for crels in grouped_rels.values(): constraint_name = self.__create_fk_contraint_name( - tname, *[rel.name for rel in rels['rels'].values()] + crels['table'], *[rel.name for rel in crels['rels'].values()] ) self._foreign_keys_[constraint_name] = { - 'table': tname, - 'fields_local': [rel.name for rel in rels['rels'].values()], - 'fields_foreign': [rel.fk for rel in rels['rels'].values()], - 'on_delete': Field._internal_delete[rels['on_delete']] + 'table': crels['table'], + 'fields_local': [rel.name for rel in crels['rels'].values()], + 'fields_foreign': [rel.fk for rel in crels['rels'].values()], + 'on_delete': Field._internal_delete[crels['on_delete']] } def _define_virtuals_(self):