如何使用 Ecto 的时间戳将时间戳添加到现有 table?
How to add timestamps to an existing table with Ecto's timestamps?
因为 inserted_at
和 updated_at
不能 null
这行不通:
def change do
alter table(:channels) do
timestamps
end
end
** (Postgrex.Error) ERROR (not_null_violation): column "inserted_at" contains null values
是否有一种无需复制 timestamps
功能即可完成此操作的简单方法?
timestamps/1
函数接受一个选项关键字列表,你可以用它来设置默认值。
def change do
alter table(:channels) do
timestamps default: "2016-01-01 00:00:01", null: false
end
end
更新 Ecto >= 2.1
您需要使用新类型 NaiveDateTime
def change do
alter table(:channels) do
timestamps default: ~N[2017-01-01 00:00:01], null: false
end
end
如果您还有更多疑问,请查看 documentation
我想你在尝试更新记录时会得到这个,我可以想到 2 种可能的解决方案,你可以通过 运行 触摸 table 中的 inserted_at 列像这样更新查询或向您的 ecto 模型添加函数
def create_changeset(model, attrs) do
model
|> cast(attrs, @required_fields, @optional_fields)
|> update_inserted_at
end
defp update_inserted_at(changeset) do
# check if the updated field is null set a new date
end
我使用以下迁移将时间戳添加到现有 table 并用当前时间填充它们:
defmodule MyApp.AddTimestampsToChannels do
use Ecto.Migration
def up do
alter table(:channels) do
timestamps null: true
end
execute """
UPDATE channels
SET updated_at=NOW(), inserted_at=NOW()
"""
alter table(:channels) do
modify :inserted_at, :utc_datetime, null: false
modify :updated_at, :utc_datetime, null: false
end
end
def down do
alter table(:channels) do
remove :inserted_at
remove :updated_at
end
end
end
还有其他方法可以做到。比如你有一些相关的table,你可以从中借用初始时间戳:
execute """
UPDATE channels
SET inserted_at=u.inserted_at,
updated_at=u.updated_at
FROM
(SELECT id,
inserted_at,
updated_at
FROM accounts) AS u
WHERE u.id=channels.user_id;
"""
因为 inserted_at
和 updated_at
不能 null
这行不通:
def change do
alter table(:channels) do
timestamps
end
end
** (Postgrex.Error) ERROR (not_null_violation): column "inserted_at" contains null values
是否有一种无需复制 timestamps
功能即可完成此操作的简单方法?
timestamps/1
函数接受一个选项关键字列表,你可以用它来设置默认值。
def change do
alter table(:channels) do
timestamps default: "2016-01-01 00:00:01", null: false
end
end
更新 Ecto >= 2.1
您需要使用新类型 NaiveDateTime
def change do
alter table(:channels) do
timestamps default: ~N[2017-01-01 00:00:01], null: false
end
end
如果您还有更多疑问,请查看 documentation
我想你在尝试更新记录时会得到这个,我可以想到 2 种可能的解决方案,你可以通过 运行 触摸 table 中的 inserted_at 列像这样更新查询或向您的 ecto 模型添加函数
def create_changeset(model, attrs) do
model
|> cast(attrs, @required_fields, @optional_fields)
|> update_inserted_at
end
defp update_inserted_at(changeset) do
# check if the updated field is null set a new date
end
我使用以下迁移将时间戳添加到现有 table 并用当前时间填充它们:
defmodule MyApp.AddTimestampsToChannels do
use Ecto.Migration
def up do
alter table(:channels) do
timestamps null: true
end
execute """
UPDATE channels
SET updated_at=NOW(), inserted_at=NOW()
"""
alter table(:channels) do
modify :inserted_at, :utc_datetime, null: false
modify :updated_at, :utc_datetime, null: false
end
end
def down do
alter table(:channels) do
remove :inserted_at
remove :updated_at
end
end
end
还有其他方法可以做到。比如你有一些相关的table,你可以从中借用初始时间戳:
execute """
UPDATE channels
SET inserted_at=u.inserted_at,
updated_at=u.updated_at
FROM
(SELECT id,
inserted_at,
updated_at
FROM accounts) AS u
WHERE u.id=channels.user_id;
"""