'PosixPath' 对象不可订阅[GeoDjango BUG]

'PosixPath' object is not subscriptable[GeoDjango BUG]

使用 ogrinfo -so 我找到了 shapefile 的结构并基于这个结构我创建了一个模型:

from django.contrib.gis.db import models

class Villages(models.Model):
.
.
.

之后我在 models.py 的同一目录中创建了 load.py as mentioned here:

from pathlib import Path
from django.contrib.gis.utils import LayerMapping
from .models import Villages

villages_mapping = {
.
.
.
}

villages = Path(__file__).resolve().parent / 'gis' / 'villages.shp'

def run(verbose=True):
    lm = LayerMapping(Villages, villages, villages_mapping, transform=False)
    lm.save(strict=True, verbose=verbose)

然后,我尝试使用 load.py:

python3 manage.py shell > from geodata import load > load.run()

但是我看到了这个奇怪的错误:

Traceback (most recent call last):   File "<console>", line 1, in
<module>   File
"/home/maxdragonheart/DEV_FOLDER/Django/Enographiae/enographiae_dev/enographiae/geodata/load.py", line 32, in run
    lm = LayerMapping(Villages, villages, villages_mapping, transform=False)   File
"/home/maxdragonheart/DEV_FOLDER/Django/Enographiae/enographiae_dev/devenv/lib/python3.7/site-packages/django/contrib/gis/utils/layermapping.py", line 99, in __init__
    self.layer = self.ds[layer] TypeError: 'PosixPath' object is not subscriptable

编辑:

也许问题出在layermapping.py里面。我已经使用原始代码和数据复制了教程,我看到了这个:

  File "<console>", line 1, in <module>
  File "/home/maxdragonheart/DEV_FOLDER/Django/Singole APP/GeoDjango/webgis/tutorialgeodjango/load.py", line 23, in run
    lm = LayerMapping(WorldBorder, world_shp, world_mapping, transform=False)
  File "/home/maxdragonheart/DEV_FOLDER/Django/Singole APP/GeoDjango/devenv/lib/python3.7/site-packages/django/contrib/gis/utils/layermapping.py", line 100, in __init__
    self.layer = self.ds[layer]
TypeError: 'PosixPath' object is not subscriptable

编辑 2:

使用 Django 2.2 中的代码上传数据没问题。我如何报告此错误?

编辑 3:

Django 3.1.3 也有这个问题

LayerMapping API 的 Django 文档在路径的数据类型上并不是 100% 清楚,但是如果您检查源代码,您会发现它需要一个字符串或 DataSource 实例。

下面是来自source code.

的相关代码
def __init__(self, model, data, mapping, layer=0,
             source_srs=None, encoding='utf-8',
             transaction_mode='commit_on_success',
             transform=True, unique=None, using=None):
    """
    A LayerMapping object is initialized using the given Model (not an instance),
    a DataSource (or string path to an OGR-supported data file), and a mapping
    dictionary.  See the module level docstring for more details and keyword
    argument usage.
    """
    # Getting the DataSource and the associated Layer.
    if isinstance(data, str):
        self.ds = DataSource(data, encoding=encoding)
    else:
        self.ds = data
    self.layer = self.ds[layer]

注释中提到了 string path,稍后在代码中会检查 data 参数是否为字符串(在本例中为路径)初始化 DataSource实例。

只需将 Path 更改为 str 即可解决您的问题。

lm = LayerMapping(Villages, str(villages), villages_mapping, transform=False)