Modify

Ticket #779 (assigned defect)

Opened 3 years ago

Last modified 14 months ago

GeoDjango data migrations appear to not respect objects = models.GeoManager()

Reported by: griffith.rees@… Owned by: andrew
Priority: major Milestone: The Future
Component: migrations Version: 0.7.3
Keywords: Cc:

Description

Writing a data migration for GeoDjango?, I attempted to use orm.ModelName?.objects.get_or_create(coordinates=new_coordinates), but ran into the following error:

class Migration(DataMigration):

    def forwards(self, orm):
        for area_code in orm.AreaCode.objects.all():
            exchange, created = orm.Exchange.objects.get_or_create(coordinates=area_code.coordinates)
            area_code.exchange = exchange
            area_code.save()

    def backwards(self, orm):
        orm.Exchange.objects.all().delete()

    models = { ... }
Running migrations for area_codes:
 - Migrating forwards to 0004_refactor_to_exchanges.
 > area_codes:0004_refactor_to_exchanges
Traceback (most recent call last):
  File "./manage.py", line 11, in <module>
    execute_manager(settings)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/core/management/base.py", line 220, in execute
    output = self.handle(*args, **options)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/management/commands/migrate.py", line 105, in handle
    ignore_ghosts = ignore_ghosts,
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/migration/__init__.py", line 191, in migrate_app
    success = migrator.migrate_many(target, workplan, database)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/migration/migrators.py", line 221, in migrate_many
    result = migrator.__class__.migrate_many(migrator, target, migrations, database)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/migration/migrators.py", line 292, in migrate_many
    result = self.migrate(migration, database)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/migration/migrators.py", line 125, in migrate
    result = self.run(migration)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/migration/migrators.py", line 99, in run
    return self.run_migration(migration)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/migration/migrators.py", line 81, in run_migration
    migration_function()
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/south/migration/migrators.py", line 57, in <lambda>
    return (lambda: direction(orm))
  File "/Users/griff/code/envs/bbs/fidonet/area_codes/migrations/0004_refactor_to_exchanges.py", line 11, in forwards
    exchange, created = orm.Exchange.objects.get_or_create(coordinates=area_code.coordinates)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/manager.py", line 135, in get_or_create
    return self.get_query_set().get_or_create(**kwargs)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/query.py", line 366, in get_or_create
    return self.get(**kwargs), False
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/query.py", line 336, in get
    num = len(clone)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/query.py", line 81, in __len__
    self._result_cache = list(self.iterator())
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/query.py", line 269, in iterator
    for row in compiler.results_iter():
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 672, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 717, in execute_sql
    sql, params = self.as_sql()
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 65, in as_sql
    where, w_params = self.query.where.as_sql(qn=qn, connection=self.connection)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/sql/where.py", line 91, in as_sql
    sql, params = child.as_sql(qn=qn, connection=connection)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/sql/where.py", line 94, in as_sql
    sql, params = self.make_atom(child, qn, connection)
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/db/models/sql/where.py", line 165, in make_atom
    if (len(params) == 1 and params[0] == '' and lookup_type == 'exact'
  File "/Users/griff/code/envs/bbs/lib/python2.6/site-packages/django/contrib/gis/db/backends/postgis/adapter.py", line 24, in __eq__
    return (self.ewkb == other.ewkb) and (self.srid == other.srid)
AttributeError: 'str' object has no attribute 'ewkb'

This appears to be related to http://groups.google.com/group/geodjango/browse_thread/thread/11a3016a0aeceec9/c563197b7fcb7ed6?lnk=gst&q=ewkb#c563197b7fcb7ed6 which indicates that get_or_create won't work without a GeoManager?(). Since manager information is not saved in South's model freezing, it's not surprising this doesn't work. This is a very geodjango specific problem.

BTW andrew, amazing project as always. I may cite you in my DPhil :P. Hope you're well.

Attachments

Change History

comment:1 Changed 3 years ago by andrew

  • Status changed from new to assigned
  • Milestone set to The Future

Yes, this is because South doesn't freeze custom managers on objects (which is usually a good idea for sanity, but annoying here).

We'll add this at some point - and I'll schedule the ticket accordingly - but in the meantime, I recommend that you just initialise a GeoManager? during the forwards() method and use it directly - I believe you can just do

    GeoManager().contribute_to_class(orm.MyModel, "objects")

comment:2 Changed 14 months ago by anonymous

lll

View

Add a comment

Modify Ticket

Action
as assigned
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.