【问题标题】:Postgres BIGSERIAL does not share sequence when inserts are made with multiple remote fdw sources当使用多个远程 fdw 源进行插入时,Postgres BIGSERIAL 不共享序列
【发布时间】:2019-06-06 08:38:55
【问题描述】:

我正在尝试使用外部数据包装器从其他两个 Postgres 数据库插入 Postgres 数据库中的表。目标是有一个自动生成的主键,独立于源,因为会有两个以上。

我首先是这样定义表的:

目标数据库:

create table dummy (
  dummy_pk bigserial primary key
  -- other fields
);

来源数据库:

create foreign table dummy (
  dummy_pk bigserial
  -- other fields
) server ... ;

只要我只从一个来源插入,此解决方案就可以正常工作,当我尝试从另一个来源插入时,没有指定 dummy_pk,我收到以下消息:

重复密钥 (dummy_pk)=(1)

因为 postgres 尝试插入 id 为 1,所以我相信每个源外表使用的顺序是不同的。我稍微更改了源表,试图让目标表的序列完成 id 的工作:

create foreign table dummy (
  dummy_pk bigint
  -- other fields
) server ... ;

这次我得到了一个不同的错误:

NULL 值违反了 «dummy_pk » 列上的 NOT NULL 约束

因此我相信源服务器会向 dummy_pk 为空的目标发送查询,而目标不会将其替换为默认值。

那么,有没有一种方法可以强制在源上执行的查询中使用目标的序列?也许我必须分享那个序列,我可以创建一个外来序列吗?我无法删除外部表上的列,因为我需要读取权限。

谢谢!

【问题讨论】:

    标签: sql postgresql primary-key postgres-fdw


    【解决方案1】:

    从外部表中删除dummy_pk,这样目标表就不会得到NULL或值,因此如果没有指定DEFAULT,则退回到DEFAULTNULL。如果您尝试将DEFAULT 传递给外部表,它将尝试使用外部表的DEFAULT 值。

    create foreign table dummy (
      /*dummy_pk bigserial,*/
      column1 text,
      column2 int2,
      -- other fields
    ) server ... ;
    

    另一种方法是使用dblink 从目标服务器获取序列值,但我认为这更好(如果您可以负担得起从外部表中删除此列)。

    【讨论】:

    • 感谢您的安得。我在其他查询中需要该列。我可以在同一台服务器中引用同一个远程表时创建两个外部表吗?我可以创建一个没有 pk,一个有?
    • 是的,如果它们不同,只需要在目标服务器中指定模式和/或表名(如果您有“重复”外部表,则必须指定)OPTIONS (schema_name 'some_schema', table_name 'some_name')
    • 是的,尽管他们有相同的名字,但已经做到了,只是为了确定,谢谢。
    猜你喜欢
    • 2016-07-14
    • 2011-06-29
    • 2020-07-20
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 2011-06-06
    相关资源
    最近更新 更多