# Buggy code
def migrate_unitdata(apps, schema_editor):
    db_alias = schema_editor.connection.alias

    Unit = apps.get_model("trans", "Unit")

    for model in (apps.get_model(*args) for args in MODELS):
        # Create new objects for each related unit
        for obj in model.objects.using(db_alias).filter(unit=None).iterator():
            units = Unit.objects.using(db_alias).filter(
                content_hash=obj.content_hash,
                translation__component__project=obj.project,
            )
            if obj.language is None:
                units = units.filter(translation__language=obj.project.source_language)
            else:
                units = units.filter(translation__language=obj.language)
            # Using __getstate__ would be cleaner, but needs Django 2.0
            state = dict(obj.__dict__)
            del state["_state"]
            del state["id"]
            del state["unit_id"]
            for unit in units:
                if model.objects.using(db_alias).filter(unit=unit, **state).exists():
                    continue
                model.objects.using(db_alias).create(unit=unit, **state)

        # Remove old objects without unit link
        model.objects.using(db_alias).filter(unit=None).delete()


# Traceback (AttributeError)
Applying trans.0053_unitdata...Traceback (most recent call last):
File "/home/ubuntu/weblateenv/bin/weblate", line 11, in <module>
sys.exit(main())
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/weblate/runner.py", line 34, in main
execute_from_command_line(argv)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 204, in handle
fake_initial=fake_initial,
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 115, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/db/migrations/migration.py", line 126, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/django/db/migrations/operations/special.py", line 193, in database_forwards
self.code(from_state.apps, schema_editor)
File "/home/ubuntu/weblateenv/local/lib/python2.7/site-packages/weblate/trans/migrations/0053_unitdata.py", line 24, in migrate_unitdata
state = obj.__getstate__()
AttributeError: 'Comment' object has no attribute '__getstate__'
Sentry is attempting to send 1 pending error messages
Waiting up to 10 seconds

# Fixed code
def migrate_unitdata(apps, schema_editor):
    db_alias = schema_editor.connection.alias

    Unit = apps.get_model("trans", "Unit")

    for model_args, fields in MODELS:
        model = apps.get_model(*model_args)
        # Create new objects for each related unit
        for obj in model.objects.using(db_alias).filter(unit=None).iterator():
            units = Unit.objects.using(db_alias).filter(
                content_hash=obj.content_hash,
                translation__component__project=obj.project,
            )
            if obj.language is None:
                units = units.filter(translation__language=obj.project.source_language)
            else:
                units = units.filter(translation__language=obj.language)
            # Using __getstate__ would be cleaner, but needs Django 2.0
            state = {field: getattr(obj, field) for field in fields}
            for unit in units:
                if model.objects.using(db_alias).filter(unit=unit, **state).exists():
                    continue
                created = model.objects.using(db_alias).create(unit=unit, **state)
                # Migrate suggestion votes
                if model_args == ("trans", "Suggestion"):
                    for vote in obj.vote_set.all():
                        created.vote_set.create(user=vote.user, value=vote.value)

        # Remove old objects without unit link
        model.objects.using(db_alias).filter(unit=None).delete()