Экранирование строк Unicode для MySQL в Python (исключая исключения. UnicodeEncodeError) - PullRequest
4 голосов
/ 18 октября 2010

Я использую Twisted для асинхронного доступа к нашей базе данных в Python. Мой код выглядит так:

from twisted.enterprise import adbapi
from MySQLdb import _mysql as mysql

...

txn.execute("""
    INSERT INTO users_accounts_data_snapshots (accountid, programid, fieldid, value, timestamp, jobid)
    VALUES ('%s', '%s', '%s', '%s', '%s', '%s')
""" % (accountid, programid, record, mysql.escape_string(newrecordslist[record]), ended, jobid))

Это работало, пока я не наткнулся на этот символ: ®, из-за которого поток генерировал исключение: `exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\xae' in position 7: ordinal not in range(128)

Однако, если я не использую MySQLdb_mysql.escape_string (), я получаю ошибки базы данных, когда ввод содержит кавычки и т. Д. (Конечно). Исключение происходит до того, как к базе данных осуществляется доступ, поэтому сортировка базы данных, похоже, не имеет никакого значения.

Каков наилучший способ избежать этого контента, не создавая исключений для символов Юникода? Идеальное решение - это то, где я могу передавать символы Unicode, которые не будут мешать запросу, в MySQL без каких-либо ограничений; однако допустимо удаление строки символов Юникода, замена их на вопросительные знаки, искажение или что-либо еще, что остановит сбои.

Ответы [ 2 ]

11 голосов
/ 18 октября 2010

Не форматируйте строки, подобные этой.Это огромная дыра в безопасности.Невозможно сделать цитату правильно самостоятельно.Не пытайтесь.

Используйте второй параметр для «выполнения».Проще говоря, вместо txn.execute("... %s, %s ..." % ("xxx", "yyy")) сделайте txn.execute("... %s, %s ...", ("xxx", "yyy")).Обратите внимание на запятую вместо знака процента.В других базах данных или с другой привязкой базы данных вы можете использовать другой символ вместо «% s», например ? или :1, :2, :3 или :foo:, :bar:, :baz:, но идея та же.(Документацию по paramstyle можно найти в документации DB-API 2.0 , если вам интересны альтернативы.)

Я уже писал об этом в прошлом ,Обсуждение этого поста может представлять особый интерес для вас.

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

2 голосов
/ 18 октября 2010

Вы можете попробовать:

newrecordslist [record] .decode ("utf-8")

Символ верен примерно http://www.python.org/dev/peps/pep-0249/.

...