Я мог бы частично воспроизвести с помощью крошечной 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;
}