Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django import export: update without add

I'm using 'django import export' (DIE) for importing and updating some data.

Import process starts from checking exists objects in DB, searching by values in ID-field, and if row with ID from import file not found - new entre will be created. How can i made "update only" scenario, where if 'id key' not found in DB, row will be skipped (not added new)?

my model.py

class Size(models.Model):
    id = models.AutoField(unique=True, primary_key=True, null=False, blank=False)
    height = models.SmallIntegerField()
    width = models.SmallIntegerField()


class Product(models.Model):
    id = models.AutoField(unique=True, primary_key=True, null=False, blank=False)
    vendor_code = models.CharField(unique=True, max_length=50, null=False, blank=False)
    price = models.DecimalField(null=False, blank=False)
    size = models.ForeignKey(Size, verbose_name=u'Size')

in resource.py

class ProductSyncResource(resources.ModelResource):

    class Meta:
        model = ProductVariant
        import_id_fields = ('vendor_code',)
        fields = ('vendor_code', 'price',)
        export_order = ('vendor_code', 'price', 'status', )
        skip_unchanged = True
        report_skipped = True
        dry_run = True

import table (xls)

enter image description here

If vendor_code 'Tк-12856' (Cell A3) will be not found, then DIE will try to add this row, and:

  1. We will get error from DB (foreignKey check for column 'size')
  2. I don't need to add this row to DB in my 'update scenario'
like image 785
Nikita Bel Avatar asked Oct 25 '25 04:10

Nikita Bel


1 Answers

Finally i got it by overriding skip_row. Fields now can be 'null=False' and will be imported only rows with known import_id_field values.

class VariantSyncResource(resources.ModelResource):

    class Meta:
        model = ProductVariant
        import_id_field = 'vendor_code'
        import_id_fields = ('vendor_code',)
        fields = ('vendor_code', 'price', 'status', )
        export_order = ('vendor_code', 'price', 'status', )
        skip_unchanged = True
        report_skipped = False
        dry_run = True

    def skip_row(self, instance, original):
        original_id_value = getattr(original, self._meta.import_id_field)
        instance_id_value = getattr(instance, self._meta.import_id_field)
        if original_id_value != instance_id_value:
            return True
        if not self._meta.skip_unchanged:
            return False
        for field in self.get_fields():
            try:
                if list(field.get_value(instance).all()) != list(field.get_value(original).all()):
                    return False
            except AttributeError:
                if field.get_value(instance) != field.get_value(original):
                    return False
        return True
like image 189
Nikita Bel Avatar answered Oct 26 '25 17:10

Nikita Bel