【发布时间】:2015-11-05 01:54:48
【问题描述】:
当我尝试通过 alter 命令更改表中列的数据类型时...
alter table temp alter column id type bigserial;
我明白了
ERROR: type "bigserial" does not exist
如何将数据类型从 bigint 更改为 bigserial?
【问题讨论】:
标签: sql database postgresql persistence
当我尝试通过 alter 命令更改表中列的数据类型时...
alter table temp alter column id type bigserial;
我明白了
ERROR: type "bigserial" does not exist
如何将数据类型从 bigint 更改为 bigserial?
【问题讨论】:
标签: sql database postgresql persistence
听起来很多专业人士都在这个主题上......如果原始表确实有数据,那么这个困境的真正答案是首先正确设计数据库。但是,在这种情况下,更改列规则(类型)将需要对该列进行完整性验证以用于新范式。而且,不要忘记,在任何地方操作(添加/更新)该列的地方都需要调查。
如果是新表,那么简单:删除列并重新添加新列(为您处理顺序)。再次,设计,设计,设计。
我想我们都犯了这个错误。
【讨论】:
如documentation 中所述,SERIAL 不是数据类型,而是其他命令集合的快捷方式。
所以虽然你不能简单地通过改变类型来改变它,但你可以通过自己运行这些其他命令来达到相同的效果:
CREATE SEQUENCE temp_id_seq;
ALTER TABLE temp ALTER COLUMN id SET NOT NULL;
ALTER TABLE temp ALTER COLUMN id SET DEFAULT nextval('temp_id_seq');
ALTER SEQUENCE temp_id_seq OWNED BY temp.id;
更改所有者将确保在删除表/列时删除序列。它还会在pg_get_serial_sequence() 函数中为您提供预期的行为。
坚持tablename_columnname_seq 命名约定对于说服一些工具(如pgAdmin)将此列类型报告为BIGSERIAL 是必要的。请注意,psql 和 pg_dump 将始终显示底层定义,即使该列最初声明为 SERIAL 类型。
从 Postgres 10 开始,您还可以选择使用 SQL 标准 identity column,它可以无形地处理所有这些,并且您可以轻松地将其添加到现有表中:
ALTER TABLE temp ALTER COLUMN id
ADD GENERATED BY DEFAULT AS IDENTITY
【讨论】:
SERIAL 类型。如果您查看带有BIGSERIAL 的表的pg_dump 输出,您只会看到BIGINT 和一个序列(并且自己创建BIGINT 和序列与使用@987654336 完全相同@关键字)。请注意,从 Postgres 10 开始,您可以选择将其转换为 identity column。
这是一个简单的解决方法:
ALTER TABLE table_name drop column column_name, add column column_name bigserial;
【讨论】:
ALTER从BIGINTEGER 到BIGSERIAL 的列以使其自动递增不起作用。 BIGSERIAL is not a true type, it is a trick that automates PK and SEQUENCE creation.
您可以自己创建一个序列,然后将其指定为列的默认值:
CREATE SEQUENCE "YOURSCHEMA"."SEQNAME";
ALTER TABLE "YOURSCHEMA"."TABLENAME"
ALTER COLUMN "COLUMNNAME" SET DEFAULT nextval('"YOURSCHEMA"."SEQNAME"'::regclass);
ALTER TABLE "YOURSCHEMA"."TABLENAME" ADD CONSTRAINT pk PRIMARY KEY ("COLUMNNAME");
【讨论】:
NULL 或非唯一的现有行,则添加PRIMARY KEY 约束将失败。 (您假设用户还没有主键。SERIAL 不只是用于 PK,SERIAL 并不意味着 SERIAL PRIMARY KEY)。此外,如果表有现有行,您需要setval 序列以确保它从第一个空闲标识符开始,LOCKing 表首先防止并发INSERTs。