带有南方的geodjango会导致使用spatialight db“重复列名称错误”

时间:2013-02-16 14:43:42

标签: python django django-south geodjango

我有geodjango的自定义字段:

from django.contrib.gis.db import models as geomodels

class PointField(geomodels.PointField):
    def formfield(self, **kwargs):
        defaults = {
            'form_class': CustomFormField
        }
        defaults.update(kwargs)
        return super(PointField, self).formfield(**defaults)


try:
    from south.modelsinspector import add_introspection_rules
    from south.introspection_plugins.geodjango import rules

    add_introspection_rules(rules, ["^project\.apps\.appname\.fields\.PointField"])
except ImportError:
    pass

和Django-South Migration:

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding field 'Address.geoposition'
        db.add_column('company_address', 'geoposition',
                      self.gf('project.apps.appname.fields.PointField')(srid=900913, geography=True),
                      keep_default=False)


    def backwards(self, orm):
        # Deleting field 'Address.geoposition'
        db.delete_column('company_address', 'geoposition')

执行此迁移时,我收到错误:

AddGeometryColumn() error: "duplicate column name: geoposition"
CreateSpatialIndex() error: either "company_address"."geoposition" isn't a Geometry column or a SpatialIndex is already defined

我已经没有想法,也不知道如何解决这个问题。

软件:

  • Django 1.4
  • spatialight 3.0.1
  • gdal 1.9.2
  • 南0.7.6

db的地理元数据是:

subprocess.call(["spatialite", settings.DATABASES['default']['NAME'], "SELECT InitSpatialMetaData();"])

和srs条目被添加:

from django.contrib.gis.utils import add_srs_entry
add_srs_entry(900913)

当我禁用迁移时,我没有错误。禁用迁移的代码:

SOUTH_MIGRATION_MODULES = {
    'appname': 'ignore',
}

但我需要一切都能正常运行。是什么原因引起了这个问题?

2 个答案:

答案 0 :(得分:2)

通过代码挖掘,传统的alter table语句不适用于空间字段,它会尝试创建一个" None"列,然后使用AddGeometryColumn命令实际创建它。但是,南方似乎没有得到提示,因此,AddGeometryColumn失败,因为列已经存在。

仍然试图找到答案,但我希望它只是升级到新版本。我会让你发布!

Django source

答案 1 :(得分:0)

您正在尝试覆盖现有的模型字段,因此您必须对基类进行修补以使其正常工作。

E.g。像这样的东西应该做的伎俩

from django.contrib.gis.db.models import Address

class CustomPointField(geomodels.PointField):
    def formfield(self, **kwargs):
        defaults = {
            'form_class': CustomFormField
        }
        defaults.update(kwargs)
        return super(PointField, self).formfield(**defaults)

Address.add_to_class('geoposition', CustomPointField())

我不确定南方会不会选择这个,所以你可能需要一个新的syncdb或手动更改。