2013-05-16 75 views
2

我有一個生成SQLite3數據庫的Ruby腳本。以CSV導出SQLite3表的內容

我希望能夠生成包含其中一個數據庫表的「output.csv」文件。

有沒有辦法在Ruby中處理?

回答

3

這是很容易與Sequelto_csv

require 'sequel' 
DB = Sequel.sqlite 
# since Sequel 3.48.0 to_csv is deprecated, 
# we must load the to_csv feature via a extension 
DB.extension(:sequel_3_dataset_methods) #define to_csv 
DB.create_table(:test){ 
    Fixnum :one 
    Fixnum :two 
    Fixnum :three 
} 
#Prepare some test data 
5.times{|i| 
    DB[:test].insert(i,i*2,i*3) 
} 

File.open('test.csv', 'w'){|f| 
    f << DB[:test].to_csv 
} 

結果是:

one, two, three 
0, 0, 0 
1, 2, 3 
2, 4, 6 
3, 6, 9 
4, 8, 12 

在我的測試中,我曾與行結束的問題,所以我需要一個額外的gsub

File.open('test.csv', 'w'){|f| 
    f << DB[:test].to_csv.gsub("\r\n","\n") 
} 

如果您想要不帶標題行的導出,我們Èto_csv(false)

備註:

  • .to_csv因爲續集3.48.0(2013年6月1日)已過時。 您可以使用舊版本gem 'sequel', '< 3.48.0'或加載擴展sequel_3_dataset_methods)。

要獲取其他分隔符和其他CSV的功能支持,你可以使用續集和CSV的組合:

require 'sequel' 
require 'csv' 
#Build test data 
DB = Sequel.sqlite 
DB.create_table(:test){ 
    Fixnum :one 
    Fixnum :two 
    Fixnum :three 
    String :four 
} 
#Prepare some test data 
5.times{|i| 
    DB[:test].insert(i,i*2,i*3, '<a href="www.test.com">test, no %i</a>' % i) 
} 

#Build csv-file 
File.open('test.csv', 'w'){|f| 
    DB[:test].each{|data| 
    f << data.values.to_csv(:col_sep=>';') 
    } 
} 

結果:

0;0;0;"<a href=""www.test.com"">test, no 0</a>" 
1;2;3;"<a href=""www.test.com"">test, no 1</a>" 
2;4;6;"<a href=""www.test.com"">test, no 2</a>" 
3;6;9;"<a href=""www.test.com"">test, no 3</a>" 
4;8;12;"<a href=""www.test.com"">test, no 4</a>" 

作爲替代你可修補Sequel :: Dataset(修改後的代碼,來自marcalc at Github的帖子):

class Sequel::Dataset 
    require 'csv' 
    # 
    #Options: 
    #* include_column_titles: true/false. default true 
    #* Other options are forwarded to CSV.generate 
    def to_csv(options={}) 
     include_column_titles = options.delete(:include_column_titles){true} #default: true 
     n = naked 
     cols = n.columns 
     csv_string = CSV.generate(options) do |csv| 
     csv << cols if include_column_titles 
     n.each{|r| csv << cols.collect{|c| r[c] } } 
     end 
     csv_string 
    end 
end 
+0

好吧,逗號和行結束可能是一個問題,因爲我將在我的字段中有用戶生成的html代碼。內置「.mode csv」的sqlite可以很好地避免逗號和行結束,有沒有辦法直接從ruby調用它? – TopperH

+0

我擴展了我的答案。該示例使用另一列分隔符和「被屏蔽。 – knut

1
# Assume that model is an activerecord model 
@secrets = Model.all 
@csv = CSV.generate do |csv| 
    @secrets.each { |secret| 
      csv << ["#{secret.attr1.to_s}", "#{secret.attr2.to_s"] # and so on till your row is finished 
    } 
end 
render :text => @csv, :content_type => 'application/csv' 

如果您還有其他問題,請發表評論。

+0

我不確定。如果我從sqlite3命令行導出csv,它將處理字段,換行符等內部的轉義逗號。您的方法是否足夠安全地處理字段內的html代碼? – TopperH

+0

應該是。你只需要使用[activerecord]來管理你的數據庫(https://rubygems.org/gems/activerecord) – hd1

+0

如果它是非Rails代碼庫,那麼Active Record與Sequel相比幾乎沒有什麼優勢。 –