3

我已经active_record设置为使用 Postgresql 数据库。其中一列是character varying[] (基本上是一个 varchar 数组)。

无论如何,我的导入例程然后读取一个制表符分隔的文本文件并插入记录。一切都很好,直到我到达一个数组。应转换为数组的列以逗号分隔。但是该行本身是制表符分隔的。

我正在导入的数据示例如下所示(制表符分隔):

Col1      Col2     Col3                  Col4
----------------------------------------------
Apple     Pear     Sweet,Round,Green     Fruit

Col3 像 (ruby): 一样被导入 col3.split(/,/),这给了我一个 Ruby 中的数组。但是 active_record 爆炸了:

PG::Error: ERROR: 数组值必须以“{”或维度信息开头 (ActiveRecord::StatementInvalid)

如何正确插入该列?
此外,有时 col3 将为 NULL。

4

2 回答 2

2

我能够使用以下 Ruby 代码插入:

alternatenames = '{' + s[3].split(/,/).map {|n| '"' + n + '"'}.join(",") + '}'
于 2012-04-16T15:22:30.243 回答
0

检查 Postgres 的文档:http ://www.postgresql.org/docs/9.2/static/arrays.html

您可以使用 [:My, :symbols] 或 ["My", "Strings"] 之类的数组来实例化模型,但是它(根据我的经验并形成文档中的内容)会将元素保存为字符串。

Search.create(tokens: [{hash: 'value'}, {test: "fails"}])
=> TypeError: can't cast Hash to string

然而:

[15] pry(main)> Search.create(tokens: [:G, :F])
=> #<Search id: 78, tokens: [:G, :F], created_at: "2013-12-18 06:29:36", updated_at: "2013-12-18 06:29:36">
[16] pry(main)> Search.last
=> #<Search id: 78, tokens: ["G", "F"], created_at: "2013-12-18 06:29:36", updated_at: "2013-12-18 06:29:36">

在我的测试中,我有一个 SearchEngine、Search 和 Term。

class SearchEngine < ActiveRecord::Base
  has_and_belongs_to_many :terms
  has_many :searches, through: :terms
end

class Term < ActiveRecord::Base
  has_and_belongs_to_many :searches
  has_and_belongs_to_many :searche_engines
end

class Search < ActiveRecord::Base
  has_many :rankings
  has_many :results, through: :rankings
  has_and_belongs_to_many :terms
  has_many :search_engines, through :terms
end


# These work:
# these next two are the way postgrespl says to query against the array. You get the 
Search.where(tokens: '{A,B}')
Search.where(tokens: '{C,D}').first_or_create

[3] pry(main)> Search.where(tokens: ['C','D']).first
ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR:  array value must start with "{" or dimension information

[4] pry(main)> Search.where(tokens: '{C,D}').first
=> #<Search id: 77, tokens: ["C", "D"], created_at: "2013-12-18 06:27:24", updated_at: "2013-12-18 06:27:24">

term = "accident"
Search.where("? = ANY (tokens)", term).first
=> #<Search id: 8, tokens: ["accident", "prevention", "safety"], created_at: "2013-12-18 07:48:13", updated_at: "2013-12-18 07:48:13">
Search.create(tokens: [:Aortic, :Any, :Other, :Elements])
Search.where("'Aortic' = ANY (tokens)").first
Parent.first.first_relationships.first.second_.where("'smelly' = ANY (tokens)").first
# The next one will create one with an empty array for tokens and push it into Term.searches anyway. Same thing with 'smelly'
Term.first.searches.where("':smelly' = ANY (tokens)").first_or_create do |s|   Term.first.searches << s 
end

# These error
Search.where(tokens: "Aortic").first
Search.where(tokens: [:Aortic, :Any, :Other, :Elements]).first

此外,如果您有嵌套数组,则可以使用以下命令进行 where 搜索:'{{1,2,3},{4,5,6},{7,8,9}}' 以查找具有列的行值 [[1,2,3],[4,5,6],[7,8,9]]

于 2013-12-18T06:36:23.830 回答