MySQL 8 上 GeoDjango 的 SRID 问题

问题描述 投票:0回答:1

GeoDjango 不尊重 MySQL 8 的 SRID。

我创建了一个新专栏

geo_code = PointField(srid=4326)

然后跑了

makemigrations
。在生成的迁移上运行
sqlmigrate
给出

BEGIN;
--
-- Create model Location
--
CREATE TABLE `locations_location` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `geo_code` POINT NOT NULL);
CREATE SPATIAL INDEX `locations_location_geo_code_id` ON `locations_location`(`geo_code`);
COMMIT;

了解 SRID 是如何被忽略的。

现在我添加到此列的任何内容都使用 SRID 0 - 这是不正确的。如果我使用 SRID 0 的

ST_DISTANCE
函数,我会得到错误的结果。

我尝试使用

migrations.SeparateDatabaseAndState
使用以下 SQL 创建具有正确 SRID 约束的列

ALTER TABLE backend_userprofile ADD COLUMN geocode_point POINT NULL SRID 4326;

现在,如果我尝试将数据插入此列,我会收到以下错误

django.db.utils.OperationalError: (3643, "The SRID of the geometry does not match the SRID of the
column 'geo_code'. The SRID of the geometry is 0, but the SRID of the column is 4326. 
Consider changing the SRID of the geometry or the SRID property of the column.")

Django 仍在尝试插入 SRID 0 的数据,MySQL 会引发错误,因为该列对 SRID 有限制。

有没有办法让 Django 使用正确的 SRID?

mysql django django-models geospatial geodjango
1个回答
0
投票

这远非理想的解决方案,但在某些情况下可能会有所帮助

假设您有模型

X
,其中
coordinate
作为
gis_models.PointField
,srid=4326

第一:

models.py
中的字段定义替换为简单的
CharField

# coordinate = gis_models.PointField(blank=True, null=True, srid=4326)
coordinate = models.CharField(max_length=255, blank=True, null=True)

然后介绍

ST_GeomFromText
函数的自定义定义:

class ST_GeomFromText(Func):
    function = "ST_GeomFromText"
    template = "%(function)s(%(field)s, %(srid)s)"
    output_field = PointField()

    def __init__(self, expression, srid, **extra):
        super().__init__(expression, srid=srid, **extra)

然后每当您需要更新现有字段时,请使用这样的方法:

x.coordinate = ST_GeomFromText(Point(lat, lng), srid=4326)
x.save()

它会起作用的

如果您需要此字段作为其他逻辑的点字段 bc,那么这种方法肯定没有效率,但如果您有“只写”或有限的“只读”,那么它会起作用

© www.soinside.com 2019 - 2024. All rights reserved.