Table partitioning with sequence field in postgresql12 - postgresql

Is there any problem when creating partitions of a table which has got seqence (nextval) as one of its field in postgresql 12?
Regards,
Seenu.

If you define a bigserial or identity column in a partitioned table, all partitions you create will share the same sequence. Consequently, auto-generated values will be unique across the whole partitioned table.

Related

PostgreSQL Upsert without using On Conflict clause

Is it possible to achieve Upsert in Postgres without using the On Conflict clause?
I have a requirement where I converted a normal table into a partitioned table with a partition key that was not part of the Primary Key when the table was non-partitioned.
Since the partition key is added to the primary key column list now, my Upsert statements are failing as the On Conflict clause is missing the partition key. But as per the requirement, I cannot add the partition key to the On Conflict clause as I will have more than one row for the previous primary key column combination in the partitioned table.
Hence, I want Upsert to be achieved without the On Conflict clause. Can someone suggest what alternatives would work.

postgresql partitioned table primary key issue

I am working on a requirement to create partition for customer name table in Postgresql DB. Primary Key of this table is an auto generated sequence number.
Since regular table cannot be turned into a partitioned table, I am planning to create a new partitioned table with primary key as composite key (sequence number + first letter of the customer's name).
I am not sure if it is required to define different sequence number one for each partition of customer name or defining the sequence number for partitioned table once will work.

Adding a partition from another DB to existing partitioned table in Postgres 12

Short description of a problem
I need to build a partitioned table "users" with 2 partitions located on separate servers (Moscow and Hamburg), each partition is table with columns:
id - integer primary key with auto increment
region - smallint partition key, which equals either 100 for Hamburg or 200 for Moscow
login - unique character varying with length of 100.
I intended to make sequences for id as n*1000 + 100 for Hamburg, and n*1000 + 200 for Moscow, so just looking on primary key I will know which partition it belongs to.
region is intended to be read only and never change after creation, so no records will move between partitions.
SELECT queries must be able to return records from all partitions and UPDATE queries must be able to modify records on all partitions, INSERT/DELETE queries must be able to add/delete records only to local partition, so data stored in them is not completely isolated.
What was done
Using pgAdmin4
I created a "test" table on Hamburg server, added all column info, marked it as partitioned table with partition key region and partition type List.
I created a "hamburg" partition in this table, adding primary key constraint as id,region and unique key constraint as login,region.
I created a "moscow" table on Moscow server with the same column info as "test"
I added postgres_fdw extension to Hamburg server, created Foreign server pointing to DB on Moscow server and User mapping.
I added "moscow" foreign table to Hamburg server pointing to "moscow" table on Moscow server.
What is my problem
I couldn't figure out how to attach this foreign table as second partition to "test" table.
When I tried to attach partition through pgAdmin dialog in "test" table partitions properties it shows me an error: cannot unpack non-iterable Response object
When I tried to add partition with query as follows:
ALTER TABLE public.test ATTACH PARTITION public.moscow FOR VALUES IN (200);
It shows me an error:
ERROR: cannot attach foreign table "moscow" as partition of partitioned table "test"
DETAIL: Table "test" contains unique indexes.
SQL state: 42809
I removed unique constraint from login column but it shows the same error.
When I make partitioned table with the same properties and both partitions initially located on the same server all works well, except for postgres watch for login uniqueness per-partition rather than in whole table, but I suggest this is its limitation.
So, how can I attach a table located on the second server as partition to partitioned table located on the first one?
The error message is pretty clear: Since you cannot create an index on a partitioned table, PostgreSQL cannot create a partition of the unique index. But the unique index is required to implement the constraint.
See this source comment:
/*
* If we're attaching a foreign table, we must fail if any of the indexes
* is a constraint index; otherwise, there's nothing to do here. Do this
* before starting work, to avoid wasting the effort of building a few
* non-unique indexes before coming across a unique one.
*/
Either drop the unique constraint or don't use foreign tables as partitions.
Ok, I was finally able to add a foreign table as partition to partitioned table.
It was necessary to drop primary key property on id and unique property on login columns for partitioned table
After that I was able to attach foreign table as partition to partitioned table
Later I have added primary key property on id and unique property on login columns for each local partition.
So in the end I have unique global id as it is generated by sequences for each DB with never intersected values. For login uniqueness I have to manually check global table if there is any record with it before inserting.
P.S. Hopefully, this partitioning mechanism in postgres is suitable for geographically distant regions.

Renaming postgres parent table with child partitions

is it ok to rename a parent table from which partitioned child tables are based ?
For example if I have
CREATE TABLE demos_qa (
demo_id int,
demo_date VARCHAR,
demo_text TEXT)
PARTITION BY RANGE (trxn_post_dt);
CREATE TABLE demos_2022 PARTITION OF demos_qa
FOR VALUES FROM ('2022-01-01') TO ('2023-01-01');
CREATE TABLE demos_2021 PARTITION OF demos_qa
FOR VALUES FROM ('2021-01-01') TO ('2022-01-01');
CREATE TABLE demos_2020 PARTITION OF demos_qa
FOR VALUES FROM ('2020-01-01') TO ('2021-01-01');
and I bulk load the partition tables.
I now want to rename the parent table from demo_qa to demo. Can I do that and will things work as normal without having to change the definitions of the partition tables ?
Yes, this will work.
The partitions won't be renamed though, in case you expected that.

How to write another query in IN function when partitioning

I have 2 local docker postgresql-10.7 servers set up. On my hot instance, I have a huge table that I wanted to partition by date (I achieved that). The data from the partitioned table (Let's call it PART_TABLE) is stored on the other server, only PART_TABLE_2019 is stored on HOT instance. And here comes the problem. I don't know how to partition 2 other tables that have foreign keys from PART_TABLE, based on FK. PART_TABLE and TABLE2_PART are both stored on HOT instance.
I was thinking something like this:
create table TABLE2_PART_2019 partition of TABLE2_PART for values in (select uuid from PART_TABLE_2019);
But the query doesn't work and I don't know if this is a good idea (performance wise and logically).
Let me just mention that I can solve this with either function or script etc. but I would like to do this without scripting.
From doc at https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE
"While primary keys are supported on partitioned tables, foreign keys
referencing partitioned tables are not supported. (Foreign key
references from a partitioned table to some other table are
supported.)"
With PostgreSQL v10, you can only define foreign keys on the individual partitions. But you could create foreign keys on each partition.
You could upgrade to PostgreSQL v11 which allows foreign keys to be defined on partitioned tables.
Can you explain what a HOT instance is and why it would makes this difficult?