【问题标题】:rails migration: postgresql for md5 of random string as defaultrails迁移:默认为随机字符串的md5的postgresql
【发布时间】:2023-03-12 16:30:01
【问题描述】:

Rails 3 + postgresql

我想要一个随机字符串的 sha 作为列的默认值。

所以,在我的迁移中,我有:

t.string :uniqueid, default: md5(random()::text)

但是我不能让它实际产生任何东西,我使用了反引号、引号等。从我看到的示例来看,pg 函数似乎只在 SELECT 语句中有效。

准确吗?关于如何实现这一目标的任何想法?

谢谢

【问题讨论】:

  • 您需要查看生成的 SQL,因为 md5(...) 调用作为 CREATE/ALTER TABLE 中的 DEFAULT 子句完全有效。

标签: ruby-on-rails ruby-on-rails-3 postgresql rails-activerecord rails-migrations


【解决方案1】:

注意:如果您使用的是更新版本的 Rails,您可能需要查看 brcebn's 的答案。


Rails 会尝试解释这一点:

t.string :uniqueid, default: md5(random()::text)

作为 Ruby 代码和 :default => md5(...) 在 Ruby 中没有任何意义。如果你引用它,Rails 会认为它是一个字符串,并将 uniqueid 的默认值设为字符串 'md5(random()::text)',这不会有帮助。

如果你想在一个列默认使用函数调用,你可以手动执行alter table

connection.execute(%q{
    alter table your_table alter column uniqueid set default md5(random()::text)
})

这将为您在数据库中提供所需的默认值,但您可能会注意到schema.rb 中没有提及新的默认值。如果你想要一个可用的模式,那么你必须使用SQL schema instead by putting this in your application.rb

config.active_record.schema_format = :sql

然后删除您的schema.rb 并改用structure.sql。请注意,SQL 模式转储在 3.2 之前被破坏,并且在各种 Rails 版本中都存在模式加载问题(但您始终可以psql < structure.sql 解决这个问题)。从好的方面来说,SQL 模式转储将跟踪花哨的东西真正的外键、检查约束、触发器......

顺便说一句,如果您真的想要 SHA,那么您需要查看 digest function from pgcrypto

【讨论】:

  • connection.execute(...) 是你会在 pg 控制台中执行的操作吗?
  • @cbrulak:不,您可以直接在迁移的 def updef down 方法中执行此操作。你只需要绕过所有 Rails 的东西,直接与数据库对话,connection.execute 就是这样做的。
  • 好的,成功了。但是,当创建新行时,默认值仍然为空。对这个问题有什么看法吗?
  • @cbrulak:swearing ActiveRecord。 ActiveRecord 不理解它在数据库中看到的默认值,并决定在其中抛出一个 NULL,请参阅我更新的答案以进一步了解此问题。基本上,您使用before_create 挂钩来计算Ruby 中的默认列。
  • @cbrulak:如果您有兴趣,可以更全面地了解默认值处理 over here
【解决方案2】:

你也可以这样做

t.string :token, default: -> { "md5((random())::text)" }, null: false

编辑:即使这会生成一个 32 位的随机字符串,但这并不意味着它是唯一的。我是这么想的,但我只是遇到了唯一索引错误。

【讨论】:

  • 这应该是最好的答案!
  • 感谢@KazuyaGosho,我猜它在 7 年前的 Rails 3 中不存在。 ?
  • AFAIK 这成为 Rails5 中的一个选项。这可以通过db/schema.rb 生存吗?我总是因为其他事情而切换到structure.sql,所以我不知道。
  • 我也总是切换到structure.sql。我不知道。但 100% 肯定它不是独一无二的。有两次相同的字符串是极其罕见的,但它可能会发生。
  • 这确实存在于schema.rb,如果您使用的是 rail5+ 版本,这绝对是答案
猜你喜欢
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
  • 2012-11-16
  • 2018-12-10
  • 2015-07-20
  • 1970-01-01
  • 2015-07-08
相关资源
最近更新 更多