1

I'm trying to create a model with Geospatial field. When I try to migrate I receive the following error:

 Apply all migrations: admin, auth, contenttypes, map, sessions Running migrations: Applying map.0008_territorio_geometry...Traceback (most recent call last): File "manage.py", line 21, in <module> main() File "manage.py", line 17, in main execute_from_command_line(sys.argv) File "C:\Users\Marco\Envs\um\lib\site-packages\django\core\management\__init__.py", line 401, in execute_from_command_line utility.execute() File "C:\Users\Marco\Envs\um\lib\site-packages\django\core\management\__init__.py", line 395, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "C:\Users\Marco\Envs\um\lib\site-packages\django\core\management\base.py", line 328, in run_from_argv self.execute(*args, **cmd_options) File "C:\Users\Marco\Envs\um\lib\site-packages\django\core\management\base.py", line 369, in execute output = self.handle(*args, **options) File "C:\Users\Marco\Envs\um\lib\site-packages\django\core\management\base.py", line 83, in wrapped res = handle_func(*args, **kwargs) File "C:\Users\Marco\Envs\um\lib\site-packages\django\core\management\commands\migrate.py", line 231, in handle post_migrate_state = executor.migrate( File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial) File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial) File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\migrations\executor.py", line 245, in apply_migration state = migration.apply(state, schema_editor) File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\migrations\migration.py", line 124, in apply operation.database_forwards(self.app_label, schema_editor, old_state, project_state) File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\migrations\operations\fields.py", line 110, in database_forwards schema_editor.add_field( File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\backends\base\schema.py", line 450, in add_field definition, params = self.column_sql(model, field, include_default=True) File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\backends\base\schema.py", line 223, in column_sql default_value = self.effective_default(field) File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\backends\base\schema.py", line 303, in effective_default return field.get_db_prep_save(self._effective_default(field), self.connection) File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\models\fields\__init__.py", line 821, in get_db_prep_save return self.get_db_prep_value(value, connection=connection, prepared=False) File "C:\Users\Marco\Envs\um\lib\site-packages\django\contrib\gis\db\models\fields.py", line 147, in get_db_prep_value super().get_db_prep_value(value, connection, *args, **kwargs), File "C:\Users\Marco\Envs\um\lib\site-packages\django\db\models\fields\__init__.py", line 816, in get_db_prep_value value = self.get_prep_value(value) File "C:\Users\Marco\Envs\um\lib\site-packages\django\contrib\gis\db\models\fields.py", line 190, in get_prep_value raise ValueError('Cannot use object with type %s for a spatial lookup parameter.' % type(obj).__name__) ValueError: Cannot use object with type int for a spatial lookup parameter. 

I also tried to remove attributes from my model but nothing changes. The following is my models.py

from django.contrib.gis.db import models # Create your models here. class Piano(models.Model): """Modello che rappresenta un piano""" titolo = models.CharField(max_length=100, help_text='Nome del piano') acronimo = models.CharField(max_length=100, help_text='Acronimo del piano') #fk_territorio = models.ForeignKey('Territorio', verbose_name='Territorio', on_delete=models.SET_NULL, null=True) def __str__(self): """String for representing the Model object.""" return self.titolo class Meta: verbose_name_plural = "Piani" class Territorio(models.Model): """Modello che rappresenta la tipologia di una norma""" nome = models.CharField(max_length=100, help_text='Nome del territorio') fk_tipo_territorio = models.ForeignKey('TipoTerritorio', verbose_name='Tipo Territorio', on_delete=models.SET_NULL, null=True) parent = models.ForeignKey('self', blank=True, related_name='child', help_text='Parent del Territorio', on_delete=models.SET_NULL, null=True) codice = models.PositiveIntegerField(help_text='Codice del Territorio', null=True) geometry = models.GeometryField(spatial_index=True, null=True) def __str__(self): """String for representing the Model object.""" return self.nome class Meta: verbose_name_plural = "Territori" class TipoTerritorio(models.Model): """Modello che rappresenta la tipologia di una norma""" nome = models.CharField(max_length=100, help_text='Tipologia di territorio') def __str__(self): """String for representing the Model object.""" return self.nome class Meta: verbose_name_plural = "TipiTerritorio" 

I am relatively new to Django and GeoDjango and I might be overlooking something. Any Idea on how to solve the migrate error?

EDIT: added 0008_territorio_geometry.py

# Generated by Django 3.0.4 on 2020-04-06 13:19 import django.contrib.gis.db.models.fields from django.db import migrations class Migration(migrations.Migration): dependencies = [ ('map', '0007_auto_20200406_1506'), ] operations = [ migrations.AddField( model_name='territorio', name='geometry', field=django.contrib.gis.db.models.fields.GeometryField(default=0, srid=4326), preserve_default=False, ), ] 
2
  • 2
    Can you show the migration file 0008? (btw, don't call your FK fields fk_..., they are not ids when you access them, they are actual instances of the model they refer to: territorio.fk_tipo_territorio will return an instance of TipoTerritorio so just call it territorio.tipo_territorio). Commented Apr 7, 2020 at 9:48
  • Thanks for the suggestion about the FK fields, I added the migration file in the question Commented Apr 7, 2020 at 10:22

2 Answers 2

1

You are adding the geometry field after the initial Territorio model creation, but you are not providing a default value to the field.
In order to apply this migration, Django asked you (in the terminal after the ./manage.py makemigrations part) to provide a default value manually for any existing records in the table. You must have answered 0 to that question and thus the problem arises (you have essentially added an Integer value to a Geometry field).

Since you are allowing null=True to the geometry field, the easy fix would be to:

  1. Revert the migrations to the previous one (0007_auto_20200406_1506):

    ./manage.py migrate my_app 0007_auto_20200406_1506 
  2. Delete the migration file 0008_territorio_geometry.py.

  3. Check the table django_migrations in your DB for the entry 0008_territorio_geometry and remove that as well (if it exists).
  4. Provide a default value of None to the geometry field as follows:

    geometry = models.GeometryField(spatial_index=True, null=True, default=None) 
  5. Recreate the migration naming it as you like, and then apply it:

    ./manage.py makemigrations --name 0008_territorio_geometry ./manage.py migrate 

You should be set to go :)

Sign up to request clarification or add additional context in comments.

3 Comments

step 3 is unnecessary since ./manage.py migrate my_app 0007 will remove it from db
@suhailvs Indeed, but it is always good to double-check (that is why I added the "if exists" part) I have met some cases (with multiple DBs in the same project) where the migration was not removed.
What you described is exactly what happended: I have entered 0 as a default value from the command line, I thought I was entering the value for the IntegerField. Thanks a lot!
0

`

dependencies = [ ('map', '0007_auto_20200406_1506'), ] operations = [ migrations.AddField( model_name='territorio', name='geometry', field=django.contrib.gis.db.models.fields.GeometryField(default=0, srid=4326), preserve_default=False, ), ]` 

changes

`

dependencies = [ ('map', '0007_auto_20200406_1506'), ] operations = [ migrations.AddField( model_name='territorio', name='geometry', field=django.contrib.gis.db.models.fields.GeometryField(default=0, srid=4326), preserve_default=None, ), ]` 

1 Comment

Could you please provide some explanations or comments in addition to code?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.