question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

skip_row does not detect the difference when m2m objects are being updated

See original GitHub issue

skip_row method does not the difference between ManyToMany objects in instance or original because the instance related objects remain unchanged.

When using skip_row all models where m2m changed are detected as unchanged thus the whole transaction is skipped

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:4
  • Comments:5

github_iconTop GitHub Comments

1reaction
mxreppycommented, Apr 11, 2018

Am I missing something or did you cache the file row data in _row somewhere else (looking at the 0.7.0 & 1.0.0 releases

0reactions
raphodncommented, Apr 24, 2020

I also struggled to update a M2M field which was defined like this:

tags = fields.Field(column_name="tags", attribute="tags", widget=ManyToManyWidget(Tag, field="name"))

What I ended up doing was to write custom code in the import_obj() method, where I manually compare the instance.tags with the row.tags, and do a instance.tags.set() with the corresponding ids (having transformed the tag names into ids beforehand). More importantly, and similarly to a comment above, I add self._m2m_updated = True (False if no changes) before calling super, so that I’m able to set skip_row() to False for these rows.

Please let me know if there is something easier to do 🤔 🙏

Full code below, hope it helps 😃

class QuestionResource(resources.ModelResource):
    category = fields.Field(
        column_name="category",
        attribute="category",
        widget=ForeignKeyWidget(Category, field="name"),
    )
    tags = fields.Field(
        column_name="tags", attribute="tags", widget=ManyToManyWidget(Tag, field="name")
    )

    def import_obj(self, instance, row, dry_run):
        """
        Manually manage M2M column
        - tags: get the row's comma-seperated tags, query their corresponding ids, check if they are
        different than the instance, and finally set them to the instance
        """
        self._m2m_updated = True
        if instance.id:
            tags = row.get("tags")
            tag_ids = []
            if tags != "":
                tags_split = tags.split(",")
                # Tag.objects.filter(name__in=tags_split) # ignores new tags
                for tag_string in tags_split:
                    # tag, created = Tag.objects.get_or_create(name=tag_string)
                    tag = Tag.objects.get(name=tag_string.strip())
                    tag_ids.append(tag.id)
                tag_ids.sort()
            if list(instance.tags.values_list("id", flat=True)) != tag_ids:
                instance.tags.set(tag_ids)
                self._m2m_updated = True
        super(QuestionResource, self).import_obj(instance, row, dry_run)

    def skip_row(self, instance, original):
        """
        Highlight row if M2M column was updated
        """
        if self._m2m_updated:
            return False
        return super(QuestionResource, self).skip_row(instance, original)

    class Meta:
        model = Question
        skip_unchanged = True
        report_skipped = True
Read more comments on GitHub >

github_iconTop Results From Across the Web

django - Can I detect ManyToManyField mutations before they ...
I was able to use the m2m_changed signal to react to the post_* actions and dispatch the broadcast after the object is all...
Read more >
Detecting modifications in ManyToMany field - Google Groups
Hello, I would like to detect changes in a ManyToMany field, to update data in the linked Model. I've two objects : class...
Read more >
What's new in 0.24.0 (January 25, 2019) - Pandas
We can construct a Series with the specified dtype. The dtype string Int64 is a pandas ExtensionDtype . Specifying a list or array...
Read more >
14 Simple Tips to save RAM memory for 1+GB dataset - Kaggle
In python notebook once a dataset loads into RAM it does not free on its own. ... Immediately we can see that most...
Read more >
MySQL Workbench
Document all SQL object types. • Document output available in different file formats. A comparison of edition features can be found at MySQL ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found