Sql 为什么我的桌子从pg_catalog.pg_类中消失了?(或者,如何查找主键列?)

Sql 为什么我的桌子从pg_catalog.pg_类中消失了?(或者,如何查找主键列?),sql,postgresql,postgresql-10,Sql,Postgresql,Postgresql 10,使用debian的postgres 10.4.2(事实上,使用postgresql docker容器) 我有几个按顺序应用的模式文件。它们创建、删除和更改表,以跟踪模式随时间的演变 然后,我运行一个程序,从pg_目录中选择表定义,为现有表生成代码包装。到目前为止,这种方法一直运作良好。(这个程序的代码是由我开发的,因此非常可疑!) 我最近将“alter table customer add field customer_stem varchar(255)not null default”和“cr

使用debian的postgres 10.4.2(事实上,使用postgresql docker容器)

我有几个按顺序应用的模式文件。它们创建、删除和更改表,以跟踪模式随时间的演变

然后,我运行一个程序,从pg_目录中选择表定义,为现有表生成代码包装。到目前为止,这种方法一直运作良好。(这个程序的代码是由我开发的,因此非常可疑!)

我最近将“alter table customer add field customer_stem varchar(255)not null default”和“create index on customer(customer_stem)”添加到新的架构文件中。 现在,在查找主键的表的查询中不再找到customer表

我运行的查询是:

    select c.relname, i.indkey 
    from pg_catalog.pg_index i 
    inner join pg_catalog.pg_class c 
      on i.indrelid=c.relfilenode 
    inner join pg_catalog.pg_tables t 
      on c.relname=t.tablename 
    where t.schemaname='public' 
      and i.indisprimary;
这应该告诉我哪些索引是表的主键。 但是,“customer”表现在不在这个查询中了——pg_类中的
relfilenode
不再匹配pg_索引中的任何内容

# select relname, relfilenode from pg_catalog.pg_class where relname='customer';
 relname  | relfilenode
----------+-------------
 customer |       16512

observe_dev=# select count(1) from pg_catalog.pg_index where indrelid=16512;
 count
-------
     0
(1 row)
这个表应该有主键和辅助索引

因此,我猜想“altertable”语句会以某种方式更改“customer”类的ID,使其不再与“pgu index”表匹配,但这似乎真的很奇怪。PSQL仍然知道定义是什么:

                                                    Table "public.customer"
    Column     |          Type          | Collation | Nullable |        Default        | Storage  | Stats target | Description
---------------+------------------------+-----------+----------+-----------------------+----------+--------------+-------------
 customer_id   | integer                |           | not null |                       | plain    |              |
 customer_name | character varying(255) |           | not null |                       | extended |              |
 customer_stem | character varying(255) |           | not null | ''::character varying | extended |              |
Indexes:
    "customer_pkey" PRIMARY KEY, btree (customer_id)
    "customer_customer_name_idx" btree (customer_name)
    "customer_customer_stem_idx" btree (customer_stem)
Referenced by:
这里也有一些重要的外交关系

因此,有两件事正在发生: 1) alter table以某种方式导致pg_目录停止更新(这似乎不太可能) 2) 我对如何查找每个表的主键的列的研究是错误的,而且我正在查看错误的表/列


很可能是2),但如果是这样,我应该如何查找这些信息呢?

我认为您可能应该加入
pg\u class.oid
列中的
pg\u index
,即:

select c.relname, i.indkey 
from pg_catalog.pg_index i 
inner join pg_catalog.pg_class c 
  on i.indrelid=c.oid  -- << HERE change c.relfilenode to c.oid 
left join pg_catalog.pg_tables t 
  on c.relname=t.tablename 
where t.schemaname='public' 
  and i.indisprimary;

因此,由于某种原因,添加带有默认值的列可能会更改关系的filenode。关于
relfilenode
和其他属性的更多详细信息,也值得阅读。

我认为您可能应该加入
pg\u class.oid
列中的
pg\u index
,即:

select c.relname, i.indkey 
from pg_catalog.pg_index i 
inner join pg_catalog.pg_class c 
  on i.indrelid=c.oid  -- << HERE change c.relfilenode to c.oid 
left join pg_catalog.pg_tables t 
  on c.relname=t.tablename 
where t.schemaname='public' 
  and i.indisprimary;

因此,由于某种原因,添加带有默认值的列可能会更改关系的filenode。有关
relfilenode
和其他属性的更多详细信息,也值得阅读。

不要在名称文本上加入目录,加入时只需要数字id(目录中的名称区分大小写,这只会让您感到困惑)。另外:您不需要pg_表目录;这只是pg_类的一个视图

WRT正在消失的目录条目:您是否提交了alter table DDL?DDL需要对目录执行一些技巧,以便对其他会话隐藏新版本



不要在名称文本上加入目录,加入时只需要数字id(目录中的名称区分大小写,这只会让您感到困惑)。另外:您不需要pg_表目录;这只是pg_类的一个视图

WRT正在消失的目录条目:您是否提交了alter table DDL?DDL需要对目录执行一些技巧,以便对其他会话隐藏新版本



“某种原因”是表必须重写。这将在PostgreSQL v11中得到改进。“某种原因”是该表必须重写。这将在PostgreSQL v11中得到改进。我需要按名称查找,因为这是我使用的表的名称!我确实犯了DDL。具体地说,我通过管道将脚本传输到psql来运行它,当脚本退出时,它将提交。我需要按名称查找,因为这是我使用的表的名称!我确实犯了DDL。具体地说,我通过管道将脚本传输到psql来运行它,当它退出时,它将提交。
select c.relname, i.indkey,i.indexrelid , i.indrelid  
    from pg_catalog.pg_index i 
    inner join pg_catalog.pg_class c 
      on i.indrelid=c.relfilenode 
where c.relname='target';