CLI скрипт с питоном с переменной, включающей специальный символ - PullRequest
0 голосов
/ 05 июля 2019

Я пытаюсь запустить скрипт CLI с python, но у меня возникают проблемы из-за специальных символов.Так что, если я запустил этот кодировщик, он будет работать нормально.Запись слоя «Innjsø» в базу данных с именем «innsjo» для имени таблицы.

ogr2ogr -f "PostgreSQL" PG:"host=localhost user=postgres  password=postgres "C:\path\GML.gml" Innsjø -nln innsjo

Однако при попытке запустить это программное обеспечение у меня возникают проблемы со специальными символами.

command = [
        "C:\\Program Files\\QGIS 2.18\\bin\\ogr2ogr.exe",
        "-f",
        "PostgreSQL",
        "PG:host=localhost user=postgres password=postgres
        loadfile,
        gml_layer_name,
        "-nln", set_table_name
    ]

subprocess.check_call(command)

Если переменная layer_name содержит специальные символы, я получаю эту ошибку.Слои только с использованием латинских символов работают просто отлично.

ERROR 1: Couldn't fetch requested layer 'Innsj°'!

У меня нет контроля над тем, как называются слои в файле GML.Как запустить скрипт CLI с python с именами, включающими специальные символы?

1 Ответ

1 голос
/ 05 июля 2019

Я мог бы частично воспроизвести с помощью крошечной C-программы, выводящей кодовые точки ее параметров (*) .Что происходит, так это то, что Python 3 в Windows - это программа, полностью поддерживающая Юникод, и поэтому subprocess использует под капотом CreateProcessW и передает командную строку широкими символами.Поэтому, когда дочерняя программа использует узкие символы, Windows преобразует широкие символы в кодовую страницу ANSI по умолчанию, которая для западноевропейских языков CP1252.

В частности, похоже, что кодовая страница консоли не используется.

Из-за этого самый надежный способ - использовать кодовую страницу 1252 в консоли: chcp 1252.

Проблема в том, что если имена ваших слоев были сохранены в виде байтовых строк cp850, теперь у вас будетнеправильные значения для всех не ASCII-символов.

В этом случае возможный обходной путь - закодировать строку как cp850 и декодировать ее как cp1252.Таким образом, когда системная библиотека закодирует ее как cp1252, вы получите ожидаемое значение cp850.

Это будет работать здесь, поскольку существует 'ø'.encode('cp850').decode('cp1252') (это символ U + 203A SINGLEПРАВИЛЬНО-ТОЧЕЧНЫЙ УГЛОВОЙ ЦИТАТЫ.Так что это должно работать:

command = [
        "C:\\Program Files\\QGIS 2.18\\bin\\ogr2ogr.exe",
        "-f",
        "PostgreSQL",
        "PG:host=localhost user=postgres password=postgres
        loadfile,
        gml_layer_name.encode('cp850').decode('cp1252'),
        "-nln", set_table_name
    ]

subprocess.check_call(command)

(*) Для ссылок вот код C, используемый для сброса кодовых точек параметров командной строки:

#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, TCHAR *argv[]) {
    for (int i = 0; i < argc; i++) {
        _tprintf(_T(">%s< "), argv[i]);

        for (TCHAR *c = argv[i]; *c != 0; c++) {
            _tprintf(_T("%02x "), (unsigned)(_TUCHAR)*c);
        }
    }
    return 0;
}
...