sat*_*ish 4 postgresql ruby-on-rails default-value rails-migrations ruby-on-rails-5
我有一个 PostGres 9.4 数据库。我想将 DATETIME 列的默认列类型更改为创建记录的时间。我认为这是正确的方法,因为这是我的 Rails 迁移
class ChangeDefaultValueForStratumWorkerSubmissions < ActiveRecord::Migration[5.1]
def change
change_column_default(:stratum_worker_submissions, :created_at, 'NOW')
end
end
Run Code Online (Sandbox Code Playgroud)
但是当我查看数据库时,默认时间戳显示为我运行迁移的时间,而不是我想要的表达式。我如何编写一个可以实现我想要的迁移?
Column | Type | Modifiers
-------------------+-----------------------------+----------------------------------------------------------------------------
id | integer | not null default nextval('stratum_worker_submissions_id_seq'::regclass)
stratum_worker_id | integer |
created_at | timestamp without time zone | not null default '2018-04-04 19:46:22.781613'::timestamp without time zone
Run Code Online (Sandbox Code Playgroud)
它没有很好的文档记录,但您可以提供 lambda 作为迁移中的默认值,这将做正确的事情。如果你这样说:
def change
change_column_default :stratum_worker_submissions, :created_at, -> { 'now()' }
end
Run Code Online (Sandbox Code Playgroud)
那么该列的默认值将被设置为,并且在该列需要默认值之前不会调用now()数据库函数。now()然后如果你\d stratum_worker_submissions进去psql你会看到:
created_at | timestamp without time zone | not null default now()
Run Code Online (Sandbox Code Playgroud)
如预期的。迁移运行时将评估任何其他默认值,并且您最终将得到一个固定时间戳作为默认值。
或者,您始终可以使用 SQL 手动完成此操作:
def up
connection.execute(%q(
alter table stratum_worker_submissions
alter column created_at
set default now()
))
end
def down
connection.execute(%q(
alter table stratum_worker_submissions
alter column created_at
drop default
))
end
Run Code Online (Sandbox Code Playgroud)
请注意,如果您开始使用 SQL 手动更改架构,您可能会开始做一些不会出现的事情,db/schema.rb因为您可以快速进入 ActiveRecord 无法理解的 SQL。如果发生这种情况,您可以通过更改从db/schema.rb到db/structure.sql更改config/application.rb:
config.active_record.schema_format = :sql
Run Code Online (Sandbox Code Playgroud)
然后在修订控制中替换db/schema.rb为并使用rake 任务代替通常的任务。db/structure.sqldb:structuredb:schema
| 归档时间: |
|
| 查看次数: |
3178 次 |
| 最近记录: |