Причиной возникновения ошибки стало изменение формата вывода данных типа bytea. До версии PostgreSQL 9 форматом вывода по умолчанию был escape. Начиная с версии PostgreSQL 9 форматом вывода по умолчанию стал hex. Библиотека Npgsql этих изменений еще не учитывает.
Я нашел два способа решения этой проблемы. Первый, это изменение параметра bytea_output в конфигурационном файле postgresql.conf. Нужно убрать комментарий и установить значение escape. Второй способ, это в клиентском коде преобразовать массив из hex-формата в обычный массив байт. Что из себя представляет hex-формат можно прочитать здесь. Вот быстро набросанный код, который получает исходный массив байт:
- using (var reader = command.ExecuteReader())
- {
- reader.Read();
- data2 = (byte[])reader[0];
- byte[] data3 = new byte[(data2.Length - 1) / 2];
- for (int i = 0; i < data3.Length; ++i)
- {
- var hi = byte.Parse(((char)data2[(i + 1) * 2 - 1]).ToString(), NumberStyles.AllowHexSpecifier);
- var lo = byte.Parse(((char)data2[(i + 1) * 2]).ToString(), NumberStyles.AllowHexSpecifier);
- data3[i] = (byte)((hi << 4) | (lo & 0x0F));
- }
- }
Скорее всего есть более цивилизованные способы, но я их пока не нашел. :)
А помимо этой особенности, преимущества от перехода на новую версию заметны?
ОтветитьУдалитьЗ.Ы. Вы стационарный или авто перевели? или что-то свое?
В PostgreSQL 9 много полезных доработок, которые хотелось бы использовать http://wiki.postgresql.org/wiki/Illustrated_9_0. И потоковая репликация и безымянные блоки кода и использование индекса для IS NOT NULL... Перевел уже и стационарный и автомобильный. На выставку повезли на PostgreSQL 9.
ОтветитьУдалитьПривет, коллега.
ОтветитьУдалитьБолее цивилизованные способы:
- если клиентская библиотека использует libpq - обновить libpq до версии >= 9.0 и, возможно, пересобрать/перелинковать клиентскую библиотеку (например, psycopg2 для питона).
- установить опцию bytea_output в escape в конфиге базы.
- установить эту опцию на время соединения с помощью запроса SET bytea_output TO escape;
https://profiles.google.com/temotor/posts/USmApxGi1d9
Привет. Про опцию bytea_output у меня написано. О возможности установления значения на время соединения, это хорошее замечание, спасибо. Что касается libpg, то было бы странным если бы последняя версия работала неправильно. :)
ОтветитьУдалить