From 23bfc3c3b05baf0cf20979eb675fdbcb4971b84a Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Tue, 20 Jun 2023 15:42:25 +0200 Subject: [PATCH] re-added property imports for open data importer --- cookbook/helper/open_data_importer.py | 14 ++++-- ...operty_property_import_food_id_and_more.py | 49 +++++++++++++++++++ ...nique_open_data_slug_per_space_and_more.py | 37 ++++++++++++++ cookbook/models.py | 37 +++++++++++--- 4 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 cookbook/migrations/0191_foodproperty_property_import_food_id_and_more.py create mode 100644 cookbook/migrations/0192_food_food_unique_open_data_slug_per_space_and_more.py diff --git a/cookbook/helper/open_data_importer.py b/cookbook/helper/open_data_importer.py index f2373be6b..2644f1f98 100644 --- a/cookbook/helper/open_data_importer.py +++ b/cookbook/helper/open_data_importer.py @@ -1,6 +1,6 @@ from django.db.models import Q -from cookbook.models import Unit, SupermarketCategory, Property, PropertyType, Supermarket, SupermarketCategoryRelation, Food, Automation, UnitConversion +from cookbook.models import Unit, SupermarketCategory, Property, PropertyType, Supermarket, SupermarketCategoryRelation, Food, Automation, UnitConversion, FoodProperty class OpenDataImporter: @@ -172,6 +172,7 @@ class OpenDataImporter: food_property_list.append(Property( property_type_id=self.slug_id_cache['property'][fp['property_type']], property_amount=fp['property_value'], + import_food_id=self.slug_id_cache['food'][k], space=self.request.space, )) @@ -183,8 +184,15 @@ class OpenDataImporter: # created_by=self.request.user, # )) - Property.objects.bulk_create(food_property_list, ignore_conflicts=True, unique_fields=('space', 'food', 'property_type',)) - #Automation.objects.bulk_create(alias_list, ignore_conflicts=True, unique_fields=('space', 'param_1', 'param_2',)) + Property.objects.bulk_create(food_property_list, ignore_conflicts=True, unique_fields=('space', 'import_food_id', 'property_type',)) + + property_food_relation_list = [] + for p in Property.objects.filter(space=self.request.space, import_food_id__isnull=False).values_list('import_food_id', 'id', ): + property_food_relation_list.append(Food.properties.through(food_id=p[0], property_id=p[1])) + + FoodProperty.objects.bulk_create(property_food_relation_list, ignore_conflicts=True, unique_fields=('food_id', 'property_id',)) + + # Automation.objects.bulk_create(alias_list, ignore_conflicts=True, unique_fields=('space', 'param_1', 'param_2',)) return insert_list + update_list def import_conversion(self): diff --git a/cookbook/migrations/0191_foodproperty_property_import_food_id_and_more.py b/cookbook/migrations/0191_foodproperty_property_import_food_id_and_more.py new file mode 100644 index 000000000..5b7d682bf --- /dev/null +++ b/cookbook/migrations/0191_foodproperty_property_import_food_id_and_more.py @@ -0,0 +1,49 @@ +# Generated by Django 4.1.9 on 2023-06-20 13:07 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ('cookbook', '0190_auto_20230525_1506'), + ] + + operations = [ + migrations.SeparateDatabaseAndState( + database_operations=[ + migrations.RunSQL( + sql="ALTER TABLE cookbook_food_properties RENAME TO cookbook_foodproperty", + reverse_sql="ALTER TABLE cookbook_foodproperty RENAME TO cookbook_food_properties", + ), + ], + state_operations=[ + migrations.CreateModel( + name='FoodProperty', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('food', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.food')), + ('property', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.property')), + ], + ), + migrations.AlterField( + model_name='food', + name='properties', + field=models.ManyToManyField(blank=True, through='cookbook.FoodProperty', to='cookbook.property'), + ), + ] + ), + migrations.AddConstraint( + model_name='foodproperty', + constraint=models.UniqueConstraint(fields=('food', 'property'), name='property_unique_food'), + ), + migrations.AddField( + model_name='property', + name='import_food_id', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddConstraint( + model_name='property', + constraint=models.UniqueConstraint(fields=('space', 'property_type', 'import_food_id'), name='property_unique_import_food_per_space'), + ), + ] diff --git a/cookbook/migrations/0192_food_food_unique_open_data_slug_per_space_and_more.py b/cookbook/migrations/0192_food_food_unique_open_data_slug_per_space_and_more.py new file mode 100644 index 000000000..09865486c --- /dev/null +++ b/cookbook/migrations/0192_food_food_unique_open_data_slug_per_space_and_more.py @@ -0,0 +1,37 @@ +# Generated by Django 4.1.9 on 2023-06-20 13:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0191_foodproperty_property_import_food_id_and_more'), + ] + + operations = [ + migrations.AddConstraint( + model_name='food', + constraint=models.UniqueConstraint(fields=('space', 'open_data_slug'), name='food_unique_open_data_slug_per_space'), + ), + migrations.AddConstraint( + model_name='propertytype', + constraint=models.UniqueConstraint(fields=('space', 'open_data_slug'), name='property_type_unique_open_data_slug_per_space'), + ), + migrations.AddConstraint( + model_name='supermarket', + constraint=models.UniqueConstraint(fields=('space', 'open_data_slug'), name='supermarket_unique_open_data_slug_per_space'), + ), + migrations.AddConstraint( + model_name='supermarketcategory', + constraint=models.UniqueConstraint(fields=('space', 'open_data_slug'), name='supermarket_category_unique_open_data_slug_per_space'), + ), + migrations.AddConstraint( + model_name='unit', + constraint=models.UniqueConstraint(fields=('space', 'open_data_slug'), name='unit_unique_open_data_slug_per_space'), + ), + migrations.AddConstraint( + model_name='unitconversion', + constraint=models.UniqueConstraint(fields=('space', 'open_data_slug'), name='unit_conversion_unique_open_data_slug_per_space'), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 06a93868b..70b505b0d 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -467,7 +467,8 @@ class SupermarketCategory(models.Model, PermissionModelMixin): class Meta: constraints = [ - models.UniqueConstraint(fields=['space', 'name'], name='smc_unique_name_per_space') + models.UniqueConstraint(fields=['space', 'name'], name='smc_unique_name_per_space'), + models.UniqueConstraint(fields=['space', 'open_data_slug'], name='supermarket_category_unique_open_data_slug_per_space') ] @@ -485,7 +486,8 @@ class Supermarket(models.Model, PermissionModelMixin): class Meta: constraints = [ - models.UniqueConstraint(fields=['space', 'name'], name='sm_unique_name_per_space') + models.UniqueConstraint(fields=['space', 'name'], name='sm_unique_name_per_space'), + models.UniqueConstraint(fields=['space', 'open_data_slug'], name='supermarket_unique_open_data_slug_per_space') ] @@ -553,7 +555,8 @@ class Unit(ExportModelOperationsMixin('unit'), models.Model, PermissionModelMixi class Meta: constraints = [ - models.UniqueConstraint(fields=['space', 'name'], name='u_unique_name_per_space') + models.UniqueConstraint(fields=['space', 'name'], name='u_unique_name_per_space'), + models.UniqueConstraint(fields=['space', 'open_data_slug'], name='unit_unique_open_data_slug_per_space') ] @@ -579,7 +582,7 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin): substitute_children = models.BooleanField(default=False) child_inherit_fields = models.ManyToManyField(FoodInheritField, blank=True, related_name='child_inherit') - properties = models.ManyToManyField("Property", blank=True) + properties = models.ManyToManyField("Property", blank=True, through='FoodProperty') properties_food_amount = models.IntegerField(default=100, blank=True) properties_food_unit = models.ForeignKey(Unit, on_delete=models.PROTECT, blank=True, null=True) @@ -661,7 +664,8 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin): class Meta: constraints = [ - models.UniqueConstraint(fields=['space', 'name'], name='f_unique_name_per_space') + models.UniqueConstraint(fields=['space', 'name'], name='f_unique_name_per_space'), + models.UniqueConstraint(fields=['space', 'open_data_slug'], name='food_unique_open_data_slug_per_space') ] indexes = ( Index(fields=['id']), @@ -690,7 +694,8 @@ class UnitConversion(ExportModelOperationsMixin('unit_conversion'), models.Model class Meta: constraints = [ - models.UniqueConstraint(fields=['space', 'base_unit', 'converted_unit', 'food'], name='f_unique_conversion_per_space') + models.UniqueConstraint(fields=['space', 'base_unit', 'converted_unit', 'food'], name='f_unique_conversion_per_space'), + models.UniqueConstraint(fields=['space', 'open_data_slug'], name='unit_conversion_unique_open_data_slug_per_space') ] @@ -787,7 +792,8 @@ class PropertyType(models.Model, PermissionModelMixin): class Meta: constraints = [ - models.UniqueConstraint(fields=['space', 'name'], name='property_type_unique_name_per_space') + models.UniqueConstraint(fields=['space', 'name'], name='property_type_unique_name_per_space'), + models.UniqueConstraint(fields=['space', 'open_data_slug'], name='property_type_unique_open_data_slug_per_space') ] @@ -795,12 +801,29 @@ class Property(models.Model, PermissionModelMixin): property_amount = models.DecimalField(default=0, decimal_places=4, max_digits=32) property_type = models.ForeignKey(PropertyType, on_delete=models.PROTECT) + import_food_id = models.IntegerField(null=True, blank=True) # field to hold food id when importing properties from the open data project + space = models.ForeignKey(Space, on_delete=models.CASCADE) objects = ScopedManager(space='space') def __str__(self): return f'{self.property_amount} {self.property_type.unit} {self.property_type.name}' + class Meta: + constraints = [ + models.UniqueConstraint(fields=['space', 'property_type', 'import_food_id'], name='property_unique_import_food_per_space') + ] + + +class FoodProperty(models.Model): + food = models.ForeignKey(Food, on_delete=models.CASCADE) + property = models.ForeignKey(Property, on_delete=models.CASCADE) + + class Meta: + constraints = [ + models.UniqueConstraint(fields=['food', 'property'], name='property_unique_food') + ] + class NutritionInformation(models.Model, PermissionModelMixin): fats = models.DecimalField(default=0, decimal_places=16, max_digits=32)