Объект ‘PosixPath’ не поддается подписке [ОШИБКА GeoDjango]

#python #django #geodjango

#python #django #geodjango

Вопрос:

Используя ogrinfo -so , я нашел структуру шейп-файла и на основе этой структуры создал модель:

 from django.contrib.gis.db import models

class Villages(models.Model):
.
.
.
 

После этого я создал, load.py как указано здесь, в том же каталоге models.py :

введите описание изображения здесь

 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

Комментарии:

1. что такое PosixPath и где вы его использовали?

2. В этом проблема. Я не знаю, что это PosixPath такое. Я просто скопировал и вставил код из официального руководства

3. Я думаю, все, что вам нужно сделать, это преобразовать path в string, потому что вы используете Path , а Django ожидает либо path как str , либо DataSource instance . Измените villages на str(villages) и будем надеяться, что это все 🙂

4. Если вы добавите это в качестве ответа, я могу проголосовать за вас @Borut

5. Спасибо. Я добавил ответ с полным объяснением.

Ответ №1:

Документация Django для LayerMapping API не на 100% ясна в отношении типа данных для path, но если вы проверите исходный код, вы увидите, что он ожидает либо экземпляр string, либо экземпляр DataSource .

Ниже приведен соответствующий код из исходного кода.

 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]
 

В комментарии упоминается путь к строке, а позже в коде есть проверка, является ли data аргумент строкой (в данном случае path) при инициализации DataSource экземпляра с его помощью.

Простое изменение Path на str решит вашу проблему.

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