1

What is the recommended way to abstract out common code when writing the database schema?

I've multiple tables that have created_at and updated_at columns.

create table if not exists profiles
(
    ...
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now()
);

...

create index on profiles (created_at);
create index on profiles (updated_at);

create trigger handle_updated_at
    before update
    on profiles
    for each row
execute procedure moddatetime(updated_at);

Repeating this code for each table has the following drawbacks

  1. pain to write
  2. difficult to refactor (say you have to change created_at to created)
  3. the real intent of the code gets buried due to too much boilerplate

Other usecases

  • automatically adding an index to all foreign key constraints
  • automatically creating mapping tables to represent relation b/w two entities

Solutions I'm aware of

  1. use an ORM - most ORMs allow you to write abstract classes that don't map to any database table, but can be inherited by child classes that do map to tables.
  2. write a function that takes in a table name and alters the table to add the desired columns, triggers and indices
    create or replace function add_created_at(table_name varchar(63))
        returns void
        language plpgsql
        security invoker
    as
    $$
    begin
     execute format('alter table %I add column created_at timestamptz not null;', table_name);
    end;
    $$;
    
    I don't particularly like this because I'm being forced to encode the query as a string.

Is there a better way?

5
  • 2
    Hi, and welcome to dba.se! You could search for temporal tables - there is an extension by Vlad Arkhipov might be overkill There's also a PL/pgSQL version here. I don't know what your hacking skills are like, but you might be able to get something from these? It's really a pity that temporal functionality is not first class in PostgreSQL! Commented Nov 14, 2021 at 12:07
  • 1
    Did you find this helpful at all? Commented Jul 31, 2022 at 8:40
  • @Vérace-СлаваУкраїні I did end up creating a bunch of meta functions to alter the tables. Made the code a lot simpler to manage for me. Note that this is for a personal project. I wouldn't do something like this if I expect other people to read my code. Commented Jul 31, 2022 at 9:12
  • There is a Postgres extension for bitemporal, it is being actively developed and has already many nice features: github.com/scalegenius/pg_bitemporal Commented Jul 31, 2022 at 11:18
  • An ORM might be overkill, but using a simple scripting language (Python, Perl, JS etc) to generate the schema definition SQL will grant you the necessary abstractions (and also allows refactoring later). Commented Jul 31, 2022 at 14:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.