【问题标题】:How to I insert an array into a Postgresql table using ActiveRecord?如何使用 ActiveRecord 将数组插入 Postgresql 表?
【发布时间】:2012-04-03 14:23:06
【问题描述】:

我有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: array value must start with "{" or dimension information (ActiveRecord::StatementInvalid)

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

【问题讨论】:

标签: ruby activerecord ruby-on-rails-3.1 etl postgresql-9.1


【解决方案1】:

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

alternatenames = '{' + s[3].split(/,/).map {|n| '"' + n + '"'}.join(",") + '}'

【讨论】:

  • 哇。获得了两次反对票,因为我提供了我自己的问题的答案,这正是我想要的方式。我。问的人。大声笑
  • 您可能被否决了,因为您提出的解决方案虽然有效,但并不像其他人想要的那样优雅。他们无法提出更好的解决方案并与您分享这一事实,可能比您解决方案的质量更能说明他们。
【解决方案2】:

查看 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]] 的行

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 2022-01-01
    • 2017-05-09
    • 1970-01-01
    • 2022-11-02
    • 2018-07-05
    相关资源
    最近更新 更多