在postgresql carrierwave中逐行读取存储的文件

时间:2013-02-11 04:53:47

标签: ruby-on-rails ruby postgresql carrierwave

我正在使用carrierwave-postgresql来存储用户上传的文件。

我有一个名为FileUploader的上传者(在/app/uploaders/file_uploader.rb中)storage :postgresql_lo

上传的文件链接到名为UploadedFile的模型中的列:file_oid(在app / models / uploaded_file.rb中)mount_uploader :file_oid, FileUploader

class UploadedFile < ActiveRecord::Base
  attr_accessible :file_oid, :processed, :type
  mount_uploader :file_oid, FileUploader
end

我将文件上传为

f = UploadedFile.new
f.file_oid = params[:flat_file]
f.save!

现在,当我尝试读取文件时,read方法工作正常,但我无法获得“每个”或“打开”。

> uf = UploadedFile.find(:first)
> uf.file_oid.read # works, gives the contents of the file
> uf.file_oid.file.read # this works too
> uf.file_oid.file.each
NoMethodError: undefined method `each' for #<CarrierWave::Storage::PostgresqlLo::File:0x000000039157a0>
> uf.file_oid.file.open
NoMethodError: private method `open' called for #<CarrierWave::Storage::PostgresqlLo::File:0x000000039157a0>
> uf.file_oid.open
NoMethodError: private method `open' called for /uploadedfile_file_oid/231132:FileUploader

1 个答案:

答案 0 :(得分:0)

CarrierWave::Storage::PostgresqlLo::File课程不支持像eachopen这样的任何内容;除了阅读整个事物,编写整个事物或获得大小之外,你不能对其中一个对象做太多的事情。

但是,如果你看一下read实现,你会看到:

@uploader.model.transaction do
  lo = connection.lo_open(identifier)
  content = connection.lo_read(lo, file_length)
  connection.lo_close(lo)
  content
end

所以你可以完全绕过carrierwave-postgresql并使用connection上的基础large objectlo_openlo_read方法按块读取lo_close块}。当然,由于大对象系统不知道是什么,所以你将无法逐行读取大对象,它只知道可搜索的字节流。