如何根据latlong批量更新一个geom字段?

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

我首先尝试了一个简单的for循环的基本实现,如下图。它可以工作,但由于有10k条记录,所以耗时太长。

panoramas = Panorama.objects.all()
for panorama in panoramas:
    panorama.geo_location = Point([panorama.longitude, panorama.latitude])
    panorama.save()

基于Django的更新方法,我又尝试了这样的方法。

geo_location = Panorama.objects.all().update(
    geo_location=fromstr(f'POINT({longitude} {latitude}', srid=4326)
)

这并不可行,因为我想让Django为每条记录选择出latlong,然后根据这两个字段更新geo_location,但Django并不知道经度和纬度是什么。

有没有一种方法可以让我用update()来实现呢?

django python-3.x postgresql postgis geodjango
1个回答
0
投票

在更新操作中使用数据库中的值正是ORM F表达式 是为了。

在文档中的例子。

这个。

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed += 1
reporter.save()

可以去这个。

reporter = Reporters.objects.filter(name='Tintin')
reporter.update(stories_filed=F('stories_filed') + 1)

有了这个好处 stories_filed + 1 拉,其操作(加法)在数据库处运行。


具体例子在PostGIS SQL中(未经测试)。

UPDATE
    panorama
SET
    geom = ST_SetSRID(
        ST_Point(panorama.longitude, panorama.latitude),
        4326
    )
FROM
    panorama
;

引用: PostGIS ST_Point, PostgreSQL 更新.


0
投票

想出了如何批量更新 geom 字段的方式进行优化。在循环中单独保存每条记录是耗时很久的原因(如预测的那样),因此使用了django的 bulk_update() 这里的方法是需要的。Django bulk_update文档

panoramas = Panorama.objects.all()
for panorama in panoramas:
     panorama.geo_location = Point(panorama.longitude, panorama.latitude, srid=4326)
Panorama.objects.bulk_update(panoramas, ['geo_location'])
© www.soinside.com 2019 - 2024. All rights reserved.