ecto 中的复合主键
composite primary keys in ecto
在迁移中我们可以添加多个主键,它们都充当复合主键。我在 table 中有四个字段,其中三个是主键并且工作得很好。当我尝试添加新迁移并将第四列设为主键时。 Postgres 给我这个错误。
(Postgrex.Error) ERROR 42P16 (invalid_table_definition) multiple primary keys for table "rooms_units" are not allowed
这是我的新迁移:
alter table(:rooms_units) do
modify(:date_to, :utc_datetime, primary_key: true)
end
如果我在原始迁移中添加它,效果很好。
这是我的原始迁移:
create table(:rooms_units, primary_key: false) do
add(:room_id, references(:rooms), null: false, primary_key: true)
add(:unit_id, references(:units), null: false, primary_key: true)
add(:date_from, :utc_datetime, null: false, primary_key: true)
add(:date_to, :utc_datetime, null: false, default: fragment("'infinity'::timestamp"))
end
如果我在 date_to 列中添加 primary_key: true 则效果很好。迁移运行成功。
所以我猜语法是正确的。但它不会在新的迁移中工作。
有什么建议或解决方法吗?
谢谢
您有 a 个主键,它恰好是一个组合键。
dbname=# \d+ rooms_units
...
Indexes:
"rooms_units_pkey" PRIMARY KEY, btree (room_id, unit_id, date_from)
...
无法添加另一个主键。每个table只能有一个主键(pk的定义)。但是您可以删除当前主键并创建一个新主键。在 Ecto 中可能有更优雅的方法来做到这一点,但这有效
defmodule MyApp.Repo.Migrations.AlterRoomsUnits do
use Ecto.Migration
def change do
drop(constraint("rooms_units", "rooms_units_pkey"))
alter table(:rooms_units) do
modify(:room_id, :integer, primary_key: true)
modify(:unit_id, :integer, primary_key: true)
modify(:date_from, :utc_datetime, primary_key: true)
modify(:date_to, :utc_datetime, primary_key: true)
end
end
end
现在我们有了一个新的复合主键
dbname=# \d+ rooms_units
...
Indexes:
"rooms_units_pkey" PRIMARY KEY, btree (room_id, unit_id, date_from, date_to)
...
在迁移中我们可以添加多个主键,它们都充当复合主键。我在 table 中有四个字段,其中三个是主键并且工作得很好。当我尝试添加新迁移并将第四列设为主键时。 Postgres 给我这个错误。
(Postgrex.Error) ERROR 42P16 (invalid_table_definition) multiple primary keys for table "rooms_units" are not allowed
这是我的新迁移:
alter table(:rooms_units) do
modify(:date_to, :utc_datetime, primary_key: true)
end
如果我在原始迁移中添加它,效果很好。
这是我的原始迁移:
create table(:rooms_units, primary_key: false) do
add(:room_id, references(:rooms), null: false, primary_key: true)
add(:unit_id, references(:units), null: false, primary_key: true)
add(:date_from, :utc_datetime, null: false, primary_key: true)
add(:date_to, :utc_datetime, null: false, default: fragment("'infinity'::timestamp"))
end
如果我在 date_to 列中添加 primary_key: true 则效果很好。迁移运行成功。
所以我猜语法是正确的。但它不会在新的迁移中工作。
有什么建议或解决方法吗? 谢谢
您有 a 个主键,它恰好是一个组合键。
dbname=# \d+ rooms_units
...
Indexes:
"rooms_units_pkey" PRIMARY KEY, btree (room_id, unit_id, date_from)
...
无法添加另一个主键。每个table只能有一个主键(pk的定义)。但是您可以删除当前主键并创建一个新主键。在 Ecto 中可能有更优雅的方法来做到这一点,但这有效
defmodule MyApp.Repo.Migrations.AlterRoomsUnits do
use Ecto.Migration
def change do
drop(constraint("rooms_units", "rooms_units_pkey"))
alter table(:rooms_units) do
modify(:room_id, :integer, primary_key: true)
modify(:unit_id, :integer, primary_key: true)
modify(:date_from, :utc_datetime, primary_key: true)
modify(:date_to, :utc_datetime, primary_key: true)
end
end
end
现在我们有了一个新的复合主键
dbname=# \d+ rooms_units
...
Indexes:
"rooms_units_pkey" PRIMARY KEY, btree (room_id, unit_id, date_from, date_to)
...