ruby-on-rails - 如何使用 change_column 在 rails migration postgres 中使用 hstore 生成正确的 sql

标签 ruby-on-rails postgresql hstore

我需要让 hstore 在 Rails 迁移中工作。我已经通过迁移启用了 hstore,现在,我正在尝试生成正确的 sql 以使其正常工作,但是当我运行 db:migrate 时出现此错误;

C:\Sites\Peoples_Profiles>rails db:migrate
rails aborted!
SyntaxError: C:/Sites/Peoples_Profiles/db/migrate/20180407073155_add_hstore_hash_to_urls.rb:4: syntax error, unexpected '\n', expecting =>
C:/Sites/Peoples_Profiles/db/migrate/20180407073155_add_hstore_hash_to_urls.rb:10: syntax error, unexpected end-of-input, expecting keyword_end
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

迁移看起来像这样。

class AddHstoreHashToUrls < ActiveRecord::Migration[5.0]

  def self.up
    change_column :users, :urls, default: {}, "hstore USING urls::hstore" 
  end

  def self.down
    change_column :users, :urls, :text
  end
end

为该列获取类型集的正确 sql 是什么?为什么我会收到换行符错误?

更新 我的 url 像这样存储在 db 中

 urls: {"url1"=>"", "url2"=>"", "url3"=>"", "url4"=>"", "url5"=>""}

所以我认为 postgres 正在提示,因为它正在尝试转换此代码..

所以在检查了 rails 实际上是如何引入参数后,它看起来像这样

 ["urls", "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nurl1: http://hello\nurl2: http://jack\nurl3: http://boo\nurl4: ''\nurl5: ''\n"]

不幸的是,不确定它在数据库中是否看起来像这样,但我说在某些地方有一个\n 导致了这个错误。将不得不进一步追求这一点。

...我现在意识到\n 将来自序列化哈希到 YAML 的转换。

最佳答案

大概你开始于:

serialize :urls

在您的模型中,因此您的哈希将作为 YAML 存储在数据库中。没有从 YAML 文本到 hstore 的类型转换,因此您的使用:

USING urls::hstore

不会工作。没有简单的方法可以在 PostgreSQL 中可靠地解析 YAML,因此最好的选择是:

  1. users.urls 列重命名为 users.yaml_urls
  2. 添加一个新的 urls 列(最好是)jsonb 类型,但如有必要,您可以使用 hstorejsonb 是 future ,将在未来得到更好的支持。
  3. 将数据库中的每个 yaml_urls 值读入 Ruby。
  4. 使用 h = YAML.load(yaml_from_db) 将该 YAML 字符串转换为散列。
  5. 将哈希编码为 JSON (h.to_json) 并将其放回数据库中。
  6. 如果需要,使 urls NOT NULL 并删除 yaml_urls 列。

我建议使用低电平 pg interface为此,因为您不希望 ActiveRecord 东西妨碍您,您能否在 ApplicationRecord.connection.raw_connection 中找到这样的连接。我这样说是因为您不希望数据迁移以任何方式与模型交互,并且低级接口(interface)支持占位符,因此您可以避免转义和引用问题。

该过程假设您没有那么多数据,或者等同地,您的应用程序可以在您修复数据库时离线。如果不是这种情况,那么您需要维护这两种格式(添加一个新的 jsonb 列,在 urls 时写入和读取模型内部的两种格式urls= 在修复数据时被调用,然后在稍后清理。

关于ruby-on-rails - 如何使用 change_column 在 rails migration postgres 中使用 hstore 生成正确的 sql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49705438/

相关文章:

ruby-on-rails - 如何避免在简单的登陆注册表单中被其他人覆盖 hstore 记录?

ruby-on-rails - rails多态关联中多列索引的顺序

javascript - 如何使用 .js.erb 将 ruby​​ 数据结构转换为 javascript 数据结构?

python - 如何将 Postgres 的 Hstore 列与 flask-sqlalchemy 一起使用?

postgresql - 如果我将某些表的 autovacuum 比例因子设置为零,会对数据库产生不利影响吗?

具有命名连接的 PostgreSQL dblink

postgresql - 在 View 中使用 hstore 比较转储和恢复 PostgreSQL 数据库失败

ruby-on-rails - 使用 Rails 验证,如何将短语列入白名单,例如 "Learn Ruby"

mysql - 试图了解 Rails 测试的工作原理并遇到模型问题

sql - 如何在 PostgreSQL 中调试公用表表达式?