I use knex to create a postgres table as following:
knex.schema.createTable('users', table => {
table.bigIncrements('user_id');
....
})
But after the table was created, the column user_id is a integer not the serial as expected.
The sql get by the pgAdmin is as following:
CREATE TABLE public.users
(
user_id bigint NOT NULL DEFAULT nextval('users_user_id_seq'::regclass),
....
)
And the consequence is that when I do insert statement, the user_id won't auto increment as expected.
Any gives?
====================
Currently I just changed to mysql connection, and the inserting works well. But if I changed the database back to postgresql, then inserting would fail due to the duplication of user_id. The code can be found here: https://github.com/buzz-buzz/buzz-service
serial and bigserial are not real types they are just shorthand for what pgAdmin is showing.
You will also find that a sequence has been created with the name users_user_id_seq when you look under sequences in pgAdmin.
Related
Postgresql lost the autoincrement feature after a restore. My database was created on Windows 10 (v 10.1) and I restored it to Postgresql on Ubuntu (v 9.6). Now that I posted the question I saw that the versions are different. I didn't use any obscure feature, only tables, functions, and columns with serials. Also, the restore process didn't complain about anything. I checked the dump options but I couldn't find anything that caused the problem.
With Pgadmin right-clicking the table > scripts > create a script on my original table gives this:
CREATE TABLE public.produto
(
produto_id integer NOT NULL DEFAULT nextval('produto_produto_id_seq'::regclass),
...
);
In my server, the restored database. It seems it lost the feature.
CREATE TABLE public.produto
(
produto_id integer NOT NULL,
...
);
You didn't check for errors during restore of the database; there should have been a few.
A dump of a table like yours will look like this in PostgreSQL v10 (this is 10.3 and it looks slightly different in 10.1, but that's irrelevant to this case):
CREATE TABLE public.produto (
produto_id integer NOT NULL
);
ALTER TABLE public.produto OWNER TO laurenz;
CREATE SEQUENCE public.produto_produto_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE public.produto_produto_id_seq OWNER TO laurenz;
ALTER SEQUENCE public.produto_produto_id_seq
OWNED BY public.produto.produto_id;
ALTER TABLE ONLY public.produto
ALTER COLUMN produto_id
SET DEFAULT nextval('public.produto_produto_id_seq'::regclass);
Now the problem is that AS integer was introduced to CREATE SEQUENCE in PostgreSQL v10, so that statement will fail with a syntax error in 9.6.
What is the consequence?
The table is created like in the first statement.
The third statement creating the sequence fails.
All the following statements that require the sequence will also fail.
Note: It is not supported to downgrade PostgeSQL with dump and restore.
The solution is to manually edit the dump until it works, in particular you'll have to remove the AS integer or AS bigint clause in CREATE SEQUENCE.
Postgresql lost the autoincrement feature after a restore. My database was created on Windows 10 (v 10.1) and I restored it to Postgresql on Ubuntu (v 9.6). Now that I posted the question I saw that the versions are different. I didn't use any obscure feature, only tables, functions, and columns with serials. Also, the restore process didn't complain about anything. I checked the dump options but I couldn't find anything that caused the problem.
With Pgadmin right-clicking the table > scripts > create a script on my original table gives this:
CREATE TABLE public.produto
(
produto_id integer NOT NULL DEFAULT nextval('produto_produto_id_seq'::regclass),
...
);
In my server, the restored database. It seems it lost the feature.
CREATE TABLE public.produto
(
produto_id integer NOT NULL,
...
);
You didn't check for errors during restore of the database; there should have been a few.
A dump of a table like yours will look like this in PostgreSQL v10 (this is 10.3 and it looks slightly different in 10.1, but that's irrelevant to this case):
CREATE TABLE public.produto (
produto_id integer NOT NULL
);
ALTER TABLE public.produto OWNER TO laurenz;
CREATE SEQUENCE public.produto_produto_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE public.produto_produto_id_seq OWNER TO laurenz;
ALTER SEQUENCE public.produto_produto_id_seq
OWNED BY public.produto.produto_id;
ALTER TABLE ONLY public.produto
ALTER COLUMN produto_id
SET DEFAULT nextval('public.produto_produto_id_seq'::regclass);
Now the problem is that AS integer was introduced to CREATE SEQUENCE in PostgreSQL v10, so that statement will fail with a syntax error in 9.6.
What is the consequence?
The table is created like in the first statement.
The third statement creating the sequence fails.
All the following statements that require the sequence will also fail.
Note: It is not supported to downgrade PostgeSQL with dump and restore.
The solution is to manually edit the dump until it works, in particular you'll have to remove the AS integer or AS bigint clause in CREATE SEQUENCE.
I'm trying to migrate my sqlite database to postgresql.
I'm new to postgresql but stuck on this simple issue.
I fist used the pgloader tool to migrate to postgresql and have a working database. I see it created the table this way:
CREATE TABLE "AOrder"
(
"OrderNumber" bigserial NOT NULL,
"BuyerName" text,
etc
)
WITH (
OIDS=FALSE
);
ALTER TABLE "AOrder"
OWNER TO postgres;
Using pgadmin3 if I run the SQL query:
select
*
from AOrder
This returns the column names plus all the data as expected.
However, the following:
select
*
from "AOrder"
This returns just the column names and no data. Where's the data?
So it's not a problem with capitalization. Is there a setting in postgresql that is making this happen?
(This is ultimately the root problem for me since I am then using Sqlachemy which inserts the double quotes in queries. I could not figure out a way to change that behavior.)
Thanks!
I've got a PgSQL 9.4.3 server setup and previously I was only using the public schema and for example I created a table like this:
CREATE TABLE ma_accessed_by_members_tracking (
reference bigserial NOT NULL,
ma_reference bigint NOT NULL,
membership_reference bigint NOT NULL,
date_accessed timestamp without time zone,
points_awarded bigint NOT NULL
);
Using the Windows Program PgAdmin III I can see it created the proper information and sequence.
However I've recently added another schema called "test" to the same database and created the exact same table, just like before.
However this time I see:
CREATE TABLE test.ma_accessed_by_members_tracking
(
reference bigint NOT NULL DEFAULT nextval('ma_accessed_by_members_tracking_reference_seq'::regclass),
ma_reference bigint NOT NULL,
membership_reference bigint NOT NULL,
date_accessed timestamp without time zone,
points_awarded bigint NOT NULL
);
My question / curiosity is why in a public schema the reference shows bigserial but in the test schema reference shows bigint with a nextval?
Both work as expected. I just do not understand why the difference in schema's would show different table creations. I realize that bigint and bigserial allow the same volume of ints to be used.
Merely A Notational Convenience
According to the documentation on Serial Types, smallserial, serial, and bigserial are not true data types. Rather, they are a notation to create at once both sequence and column with default value pointing to that sequence.
I created test table on schema public. The command psql \d shows bigint column type. Maybe it's PgAdmin behavior ?
Update
I checked PgAdmin source code. In function pgColumn::GetDefinition() it scans table pg_depend for auto dependency and when found it - replaces bigint with bigserial to simulate original table create code.
When you create a serial column in the standard way:
CREATE TABLE new_table (
new_id serial);
Postgres creates a sequence with commands:
CREATE SEQUENCE new_table_new_id_seq ...
ALTER SEQUENCE new_table_new_id_seq OWNED BY new_table.new_id;
From documentation: The OWNED BY option causes the sequence to be associated with a specific table column, such that if that column (or its whole table) is dropped, the sequence will be automatically dropped as well.
Standard name of a sequence is built from table name, column name and suffix _seq.
If a serial column was created in such a way, PgAdmin shows its type as serial.
If a sequence has non-standard name or is not associated with a column, PgAdmin shows nextval() as default value.
Here is some SQL for PostgreSQL (I know it's a silly query; I've boiled the original query down to the simplest broken code):
CREATE TABLE entity (
id SERIAL PRIMARY KEY
);
WITH new_entity
AS (INSERT INTO entity DEFAULT VALUES
RETURNING id
)
SELECT id FROM new_entity;
Here it is running on PostgreSQL 9.1:
psql:../sandbox/test.sql:3: NOTICE: CREATE TABLE will create implicit sequence "entity_id_seq" for serial column "entity.id"
psql:../sandbox/test.sql:3: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "entity_pkey" for table "entity"
CREATE TABLE
id
----
1
(1 row)
Here it is not running on PostgreSQL 8.4:
psql:../sandbox/test.sql:3: NOTICE: CREATE TABLE will create implicit sequence "entity_id_seq" for serial column "entity.id"
psql:../sandbox/test.sql:3: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "entity_pkey" for table "entity"
CREATE TABLE
psql:../sandbox/test.sql:9: ERROR: syntax error at or near "INSERT"
LINE 2: AS (INSERT INTO entity DEFAULT VALUES
Obviously, the table creation goes fine in both cases, but it wipes out on the second query in PostgreSQL 8.4. From this error message I am unable to gather exactly what the problem is. I don't know what it is that 9.1 has and 8.4 doesn't have that could result in this syntax error. It's hilariously hard to google it. I am approaching the level of desperation required to trawl through the pages of PostgreSQL release notes between 8.4 and 9.1 and finding out if anything related to WITH … AS or INSERT … RETURNING was changed or added, but before I go there I am hoping one of you has the experience and/or godly google-fu to help me out here.
Data-modifying statements in WITH were introduced in Postgres 9.1