использование pyodbc на Linux для вставки unicode или utf-8 символов в nvarchar mssql поле

В Angular 4,

HTML:

<input #fileUpload type="file" (click)="fileUpload.value = null"(change)="importFile($event)" style="display:none"
accept="image/*">
<button (click)="fileUpload.click()">  </button>

Машинопись:

importFile(event) {

if (event.target.files.length == 0) {
   console.log("No file selected!");
   return
}
  let file: File = event.target.files[0];
  // after here 'file' can be accessed and used for further process
}

При рассмотрении вопроса о будущем выборе того же файла, который не работает, Во входном теге событие щелчка, которое мы устанавливаем равным нулю, что позволяет выбрать тот же файл во второй раз.

21
задан nosklo 8 June 2009 в 04:21
поделиться

3 ответа

Я помню, что у меня возникали такие глупые проблемы с драйверами odbc, даже если в тот раз это была комбинация java + oracle.

Суть в том, что драйвер odbc явно кодирует строку запроса при отправке в БД. Даже если это поле Unicode, и если вы предоставляете Unicode, в некоторых случаях это не имеет значения.

Вам необходимо убедиться, что то, что отправлено драйвером, имеет ту же кодировку, что и ваша база данных (не только сервер, но и также база данных). В противном случае, конечно, вы получите забавные символы, потому что либо клиент, либо сервер смешивают вещи при кодировании / декодировании. Есть ли у вас какие-либо представления о кодировке (кодовая точка, как любит говорить MS), которую ваш сервер использует по умолчанию для декодирования данных?

Сопоставление не имеет ничего общего с этой проблемой :)

См. , что MS страница например. Для полей Unicode сопоставление используется только для определения порядка сортировки в столбце, не , чтобы указать, как хранятся данные.

Если вы храните данные в формате Unicode, существует уникальный способ их представления, в этом и заключается цель Unicode: нет необходимости определять кодировку, совместимую со всеми языками, которые вы собираетесь использовать :)

Здесь возникает вопрос: «Что происходит, когда я передаю серверу данные, которые являются , а не Unicode?». Например:

  • Когда я отправляю строку UTF-8 на сервер, как он ее понимает?
  • Когда я отправляю строку UTF-16 на сервер, как он ее понимает?
  • Когда я отправить на сервер строку Latin1, как он ее понимает?

С точки зрения сервера, все эти 3 строки представляют собой всего лишь поток байтов. Сервер не может угадать кодировку, в которой вы их закодировали. Это означает, что у вас возникнут проблемы, если ваш odbc-клиент отправит байтовые строки (закодированную строку) на сервер вместо отправки данных unicode : если вы это сделаете таким образом, сервер будет использовать предопределенную кодировку (это был мой вопрос: какую кодировку будет использовать сервер? Поскольку это не угадывание, это должно быть значение параметра), и если строка была закодирована с использованием другой кодировки, dzing , данные будут повреждены.

Это точно так же, как и в Python:

uni = u'Hey my name is André'
in_utf8 = uni.encode('utf-8')
# send the utf-8 data to server
# send(in_utf8)

# on server side
# server receives it. But server is Japanese.
# So the server treats the data with the National charset, shift-jis:
some_string = in_utf8 # some_string = receive()    
decoded = some_string.decode('sjis')

Просто попробуйте. Это весело. Расшифрованная строка должна быть «Привет, меня зовут Андре», но это «Привет, меня зовут Андр テ ゥ». é заменяется японским テ ゥ

Отсюда мое предложение: вам необходимо убедиться, что pyodbc может напрямую отправлять данные в формате Unicode. Если pyodbc не сможет этого сделать, вы получите неожиданные результаты.

И я описал проблему способом от клиента к серверу. Но такие же проблемы могут возникнуть при обмене данными от Сервера к Клиенту. Если Клиент не может понять данные Unicode, вы, скорее всего, столкнетесь с проблемами.

FreeTDS обрабатывает Unicode за вас.

На самом деле FreeTDS заботится обо всем за вас и переводит все данные в Unicode UCS2. ( Источник ).

  • Сервер <--> FreeTDS: данные UCS2
  • FreeTDS <--> pyodbc: закодированные строки, закодированные в UTF-8 (из / etc / freetds / freetds.conf )

Поэтому я ожидаю, что ваше приложение будет работать правильно, если вы передадите данные UTF-8 в pyodbc. Фактически, как говорится в этом билете django-pyodbc , django-pyodbc взаимодействует в UTF-8 с pyodbc, так что все будет в порядке.

FreeTDS 0.82

Однако cramm0 говорит, что FreeTDS 0.82 не полностью свободен от ошибок, и что есть существенные различия между 0.82 и официальной исправленной версией 0.82, которую можно найти здесь . Вероятно, вам стоит попробовать использовать исправленный FreeTDS


Edited : удалил старые данные, которые не имели ничего общего с FreeTDS, но имели отношение только к коммерческому драйверу odbc Easysoft. Извините.

21
ответ дан 29 November 2019 в 21:44
поделиться

Я использую UCS-2 для взаимодействия с SQL Server, а не UTF-8.

Исправление: я изменил запись .freetds.conf, чтобы клиент использовал UTF-8

    tds version = 8.0
    client charset = UTF-8
    text size = 32768

Теперь значения привязки отлично работают для строк в кодировке UTF-8. Драйвер прозрачно выполняет преобразование между UCS-2, используемым для хранения на стороне сервера данных, и закодированными строками UTF-8, передаваемыми / принимаемыми от клиента.

Это с pyodbc 2.0 на Solaris 10, работающем на Python 2.5 и FreeTDS freetds-0.82. .1.dev.20081111 и SQL Server 2008


import pyodbc
test_string = u"""Comment ça va ? Très bien ?"""

print type(test_string),repr(test_string)
utf8 = 'utf8:' + test_string.encode('UTF-8')
print type(utf8), repr(utf8)

c = pyodbc.connect('DSN=SA_SQL_SERVER_TEST;UID=XXX;PWD=XXX')

cur = c.cursor()
# This does not work as test_string is not UTF-encoded
try: 
    cur.execute('INSERT unicode_test(t) VALUES(?)', test_string)
    c.commit()
except pyodbc.Error,e:
    print e


# This one does:
try:
    cur.execute('INSERT unicode_test(t) VALUES(?)', utf8)
    c.commit()
except pyodbc.Error,e:
    print e    


Вот результат из тестовой таблицы (я вручную ввел кучу тестовых данных через Management Studio)

In [41]: for i in cur.execute('SELECT t FROM unicode_test'):
   ....:     print i
   ....:
   ....:
('this is not a banana', )
('\xc3\x85kergatan 24', )
('\xc3\x85kergatan 24', )
('\xe6\xb0\xb4 this is code-point 63CF', )
('Mich\xc3\xa9l', )
('Comment a va ? Trs bien ?', )
('utf8:Comment \xc3\xa7a va ? Tr\xc3\xa8s bien ?', )

Мне удалось добавить некоторые точки кода Unicode. непосредственно в таблицу из Management Studio с помощью диалогового окна «Редактировать первые 200 строк» ​​и ввода шестнадцатеричных цифр для кодовой точки Unicode, а затем нажатия Alt-X

2
ответ дан 29 November 2019 в 21:44
поделиться

Вы уверены, что проблема не при чтении возникает из-за INSERT? В pyodbc обнаружена ошибка. Проблема с получением данных NTEXT и NVARCHAR .

0
ответ дан 29 November 2019 в 21:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: