На моем сервере скрипт Python получает данные из базы данных в виде кортежа. Затем сценарий преобразует кортеж в строку (с помощью json.dumps()) для передачи сценарию JavaScript в браузере пользователя.
Данные включают немецкие имена, такие как Вайдмюллер. Когда скрипт Python получает эти данные, он возвращает их как Weidm\xfcller, где \xfc — это кодировка UTF-8 для ü. Все идет нормально.
Однако,
json.dumps(tableData,ensure_ascii=False)
преобразует \xfc в � json.dumps(tableData,ensure_ascii=True)
не удается: «UnicodeDecodeError: кодек 'utf8' не может декодировать байт 0xfc в позиции 5: неверный начальный байт»Чего я действительно хочу, так это того, чтобы json.dumps оставил в покое символ в кодировке UTF-8; просто передать \xfc как есть. Таким образом, сценарий JavaScript в браузере пользователя сможет выполнить декодирование. Это возможно?
Или я неправильно подхожу к проблеме?
Вот полный код:
import MySQLdb
...
# Open the data base and return a handle to it and its cursor
dataBase, dbCursor = database.OpenDB()
# Get data from the URL
fieldStore = cgi.FieldStorage()
selFieldName = selFieldValue = ''
sqlQuery = 'SELECT * FROM %s' % (database.CompTableName)
if ('fldName' in fieldStore) and ('fldValue' in fieldStore):
fldName = fieldStore['fldName'].value
fldValue = fieldStore['fldValue'].value
sqlQuery += ' WHERE %s = \'%s\'' % (fldName,fldValue)
if ('max' in fieldStore):
maxRows = fieldStore['max'].value
sqlQuery += ' LIMIT ' + maxRows
# Get the selected data in the table as a list of lists
rowsAffected = dbCursor.execute(sqlQuery)
tableData = dbCursor.fetchall()
# Close the database and return the results
dataBase.close()
jsonTableData = json.dumps(tableData,encoding='latin1',ensure_ascii=True)
print jsonTableData
И вот тестовый код:
tableData = (('item1', 'Jones',), ('item2', 'Weidm\xfcller'))
jsonTableData = json.dumps(tableData,encoding='latin1',ensure_ascii=True)
print jsonTableData
«Вы сбрасываете байты‽» Я не знаю, что означает «сброс», извините. Вы имеете в виду "конвертировать"? "в любой форме" Это не форма, это база данных.
Свалка = json.dumps
Спасибо вам за разъяснение. Нет, я не «сбрасываю» байты. Я «сбрасываю» кортеж.
И что именно содержит этот кортеж? Байты? Откуда они? Адаптер базы данных в идеале должен возвращать текст, str
, тогда это не проблема.
«И что именно содержит этот кортеж?» Пример: (('item1', 'Jones',), ('item2', 'Weidm\xfcller')). «Адаптер базы данных в идеале должен возвращать...» кортеж, включающий строки. sqlQuery = 'SELECT * FROM %s' % (database.TableName) ... dbCursor.execute(sqlQuery) ... tableData = dbCursor.fetchall() Возвращает кортеж.
Что это за адаптер базы данных? И какая версия Python? Вы, наверное, используете Python 2? Пожалуйста, предоставьте минимально воспроизводимый пример.
MySQLdb. Питон 2, да.
@DavideAndrea Это недействительный JSON, если он не закодирован в UTF-8. Отредактируйте свой вопрос, используя воспроизводимый пример.
Если вы используете Python 2, 'Weidm\xfcller'
является правильным и содержит escape-код для ü
. print
это правильно увидеть.
@Марк Толонен. TIL, что в строках JSON допускается только UTF-8. Спасибо. Теперь я рассмотрю этот вопрос в ином свете. «воспроизводимый пример» Трудно сделать, когда речь идет о доступе к базе данных: мне пришлось бы опубликовать учетные данные для входа. Я не могу так, извини.
@Дэвид, нет, ты просто установил переменную с минимальным содержимым и покажи, как записать json в файл. БД не требуется
\xfc
— это не кодировка UTF-8 для ü, это кодировка Latin-1.
>>> u'ü'.encode('latin-1')
'\xfc'
>>> u'ü'.encode('utf-8')
'\xc3\xbc'
Если вы json.dumps
отправляете текст, вы не должны получать такие символы замены:
>>> json.dumps({u"k": u"Weidmüller"})
'{"k": "Weidm\\u00fcller"}'
>>> json.dumps({u"k": u"Weidmüller"}, ensure_ascii=False)
u'{"k": "Weidm\xfcller"}'
Прежде всего убедитесь, что вы получаете из базы данных правильно декодированный текст.
«это кодировка Latin-1» Спасибо. Это то, что мне было нужно. Я решил это с помощью json.dumps(tableData,encoding='latin1',ensure_ascii=True)
@DavideAndrea Это недействительный JSON, если он не закодирован в UTF-8.
@DavideAndrea Это не то «решение», к которому я хотел, чтобы вы пришли из этого ответа. Вам следует убедиться, что ваши кортежи содержат элементы Юникода, а не элементы str. Это означает правильную настройку адаптера базы данных.
@wim Я пересмотрю свой подход, основываясь на твоем совете. Спасибо.
Вы сбрасываете байты? У вас должен быть символ ü, а не \xfc в любой форме.