Вложение двоичного файла "до неузнаваемости" для postresql и rails 4

В настоящее время у меня есть проблема с хранением файлов в виде двоичных объектов на postresql (9.3) с ruby ​​на rails (4.1.1). При открытии файла с промежуточного / рабочего сервера, который я сохранил, я получаю

unrecognizable format

Это означает, что файл (вероятно) поврежден. Я подтвердил это с помощью textedit, где загруженный с производства файл отображает "x89504e470d0a1a0a0000000d494844520000010b000001c00800000000901112f9000000097048597300000c4e00000c4e017f778c00000c4e017f778c00000c4e017f778c00000c4e017f778c00000000097048597300000c4e00000c4e017f778c2300000318694... в коде H150...".

Как ни странно, проблема возникает только в производственной среде (Centos6 + Passenger + NginX), в то время как среда разработки (MacOS) работает нормально. Более того, я не знаю, является ли это проблемой Postgres, так как после того, как я попытаюсь восстановить рабочий дамп на моей машине для разработки, файлы, которые я загружал в производство, открывались очень хорошо локально! Вот код, который создает объект data_file (тот, который содержит двоичное содержимое):

def create
  authorize! :create, :data_file # cancan authorization
  file = params[:file]
  @data_file = DataFile.new(name: file.original_filename,
                            size: file.size,
                            contents: file.read,
                            content_type: file.content_type # + some additional params)
  authorize! :update, @data_file # other cancan authorization
  if @data_file.save
    render("data_files/show", formats: :json)
  else
    render json: {errors: @data_file.errors}, status: 403
  end
end

и вот код, который отображает файл

def show
  @data_file = DataFile.find(params[:id])
  authorize! :show, @data_file
  send_data @data_file.contents, :disposition => 'attachment', :filename => @data_file.name
end

вот схема объекта datafile

create_table "data_files", force: true do |t|
  t.string   "name"
  t.integer  "user_id"
  t.integer  "project_id"

  t.string   "size"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.binary   "contents"
  t.integer  "content_type"
  t.string   "valid_from"
  t.string   "valid_until"
  t.datetime "formatted_valid_until"
  t.datetime "formatted_valid_from"
end

Было бы здорово, если бы кто-то мог помочь мне с этим вопросом. Странно, что программа ведет себя по-разному в средах, которые кажутся одинаковыми.

Заранее спасибо!

1 ответ

Решение

В результате вы смотрите шестнадцатеричную строку со значением типа bytea генерируется PostgreSQL 9.0 или выше, что происходит, когда bytea_output параметр установлен в hex,

Приложение SQL, связанное с пре-9.0 libpq не будет должным образом декодировать это содержимое и в основном извергать дословно шестнадцатеричную строку, как показано в вопросе. Предположительно, разница между вашей производственной средой и средой разработки заключается в версии libpq,

В качестве обходного пути, до обновления, вы можете заставить bytea_ouput к его старому значению по умолчанию, escapeна нескольких возможных уровнях:

  • для всего кластера, настроенного в postgresql.conf
  • для одной базы данных с ALTER DATABASE dbname SET bytea_output to 'escape';
  • для конкретного пользователя: ALTER USER username SET bytea_output to 'escape';
  • для сеанса SQL (непостоянный): SET bytea_output TO 'escape';
Другие вопросы по тегам