Сохранение содержимого текстового файла в БД: «Неверное строковое значение: ‘XeF xBB xBF # W …’ для столбца ‘contents’ в строке 1»

#python #mysql #django #file #character-encoding

#python #mysql #django #файл #кодировка символов

Вопрос:

В моем приложении Django я загружаю текстовый файл, используя file.read() для получения содержимого файла, а затем сохраняю в базе данных (используя метод Django .save()).

Я получаю следующую ошибку:

 Environment:

Request Method: POST
Request URL: http://localhost:8000/
Django Version: 1.2.5
Python Version: 2.7.1
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.admin',
 'django.contrib.markup',
 'files']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/usr/lib/pymodules/python2.7/django/core/handlers/base.py" in get_response
  100.                     response = callback(request, *callback_args, **callback_kwargs)
File "/home/mcrittenden/Dropbox/Code/dropdo-django/dropdo/files/views.py" in index
  31.                 return handle_upload(request.FILES['file'])
File "/home/mcrittenden/Dropbox/Code/dropdo-django/dropdo/files/views.py" in handle_upload
  60.     file.save()
File "/usr/lib/pymodules/python2.7/django/db/models/base.py" in save
  458.         self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/usr/lib/pymodules/python2.7/django/db/models/base.py" in save_base
  551.                     result = manager._insert(values, return_id=update_pk, using=using)
File "/usr/lib/pymodules/python2.7/django/db/models/manager.py" in _insert
  195.         return insert_query(self.model, values, **kwargs)
File "/usr/lib/pymodules/python2.7/django/db/models/query.py" in insert_query
  1524.     return query.get_compiler(using=using).execute_sql(return_id)
File "/usr/lib/pymodules/python2.7/django/db/models/sql/compiler.py" in execute_sql
  788.         cursor = super(SQLInsertCompiler, self).execute_sql(None)
File "/usr/lib/pymodules/python2.7/django/db/models/sql/compiler.py" in execute_sql
  732.         cursor.execute(sql, params)
File "/usr/lib/pymodules/python2.7/django/db/backends/util.py" in execute
  15.             return self.cursor.execute(sql, params)
File "/usr/lib/pymodules/python2.7/django/db/backends/mysql/base.py" in execute
  86.             return self.cursor.execute(query, args)
File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py" in execute
  168.         if not self._defer_warnings: self._warning_check()
File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py" in _warning_check
  82.                     warn(w[-1], self.Warning, 3)

Exception Type: Warning at /
Exception Value: Incorrect string value: 'xEFxBBxBF# W...' for column 'contents' at row 1
  

Я предполагаю (поскольку EF BB BF является символом спецификации UTF), это связано с разницей в кодировке между базой данных и файлом? Звучит ли это корректно? Если да, то как мне это исправить?

Ответ №1:

Вы на правильном пути. Проверьте кодировку вашей базы данных (это utf-8?). Если это не так, и вы хотите использовать UTF-8, измените кодировку с помощью этой SQL-команды

 alter table yourTableName DEFAULT CHARACTER SET utf8;
  

И прочтите это замечательное руководство по использованию UTF-8 в Python, если вы хотите преобразовать свою строку UTF-8 обратно.

Вы можете удалить DOM с помощью этой команды

# Удалить спецификацию из начала строки Unicode, если она существует
u.lstrip( unicode( codecs.BOM_UTF8, «utf8» ) )

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

1. Моя таблица имеет формат utf8. Но я все еще получаю эту ошибку.

Ответ №2:

Вы правы, в файле, который вы читаете, в начале вставлены символы спецификации. Вам придется проверить наличие и удалить эти символы, прежде чем передавать данные дальше. Остальная часть файла будет состоять из символов UTF-8.

Я не уверен, как определить, какой набор символов ожидает база данных.