简体   繁体   中英

Dynamic creation of partitions in postgreSQL

I would like to have a dynammic function or stored procedure that creates a partition for every new entry that hasn't a table.
I have something like this:

CREATE TABLE student(
  id int,
  name varchar(30),
  city varchar(30),
  avg float,
) PARTITION BY LIST (city);

and my function is this:

create or replace function before_insert_on_student()
returns trigger language plpgsql as $$
begin
    execute format(
        $f$
            create table if not exists %I partition of student for values in (%L);
        $f$,
        new.city,
        new.city);
    execute format(
        $f$
            insert into %I
            values (nextval('student_data_seq'), %L, %L, %L, %L);
        $f$,
        new.city,
        new.id,
        new.name,
        new.city,
        new.avg,);
    return null;
end $$;

My problem is that i'm getting this error:

ERROR: cannot make CREATE TABLE .. PARTITION OF in "student" because it is being used by active queries in this session.

I'm using PostgreSQL 14. I would appreciate some help or tips to improve this code. Thanks.

Been there, tried that, it doesn't work. As soon as you execute a statement that involves the table, it is too late to modify the definition of the table, which is what adding a partition does. There is no way to get what you want.

Some alternatives:

  • create partitions ahead of time

  • use a DEFAULT partition to contain the values what don't fit anywhere else (but beware that it may prevent you from adding new partitions in the future by containing conflicting rows)

  • have your trigger create a new table, but don't make that new table a partition right away – perhaps you could NOTIFY a LISTEN er that then attaches the partition

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM