Use config.services.postgresql.extensions, is it a functor?

I want to use config.services.postgresql.extensions later in my config to built a postStart script. Unfortunately config.services.postgresql.extensions is not simply a list of packages but a functor? How can I convert that to a list of packages?

I tried to use config.services.postgresql.finalPackage.installedExtensions but it doesn’t give the list of extensions as specified in config.services.postgresql.extensions.

I am not really sure why you are trying to use extensions for what you describe. The extensions option is a list of postgresqlXYPackages to include into the server package. Example:

extensions = with pkgs.postgresql16Packages; [ pgtap ];

For what you describe, I would just use the initialScript option like this:

grantUser = name: ''
  ALTER DATABASE ${name} OWNER TO ${name};
  GRANT ALL PRIVILEGES ON DATABASE ${name} TO ${name};
  GRANT CONNECT ON DATABASE ${name} TO ${name};
'';

initSqlScript = pkgs.writeText "init-sql-script" ''
  ${grantUser "foo"}
'';

# in your postgres server options you set:
initialScript = initSqlScript;

Does this help?

Hi,

Thank you for your reply, I have the extensions defined as

  extensions =
    ps: with ps; [
      pg_cron
      postgis
      timescaledb
      timescaledb_toolkit
      plpython3
    ];

and then it is not a list (but a functor?). I want to use the the extensions in the postStart script I’ve created:

  systemd.services.postgresql.postStart =
    let
      extensions = map lib.getName (config.services.postgresql.extensions);
    in
      ''
        psql dbname << 'EOF'
      ''
      + lib.concatLines (map (e: "CREATE EXTENSION IF NOT EXISTS ${e};") extensions);
      + ''
        EOF
      ''

The actual script contains more, but this describes the goal and problem.

Functor is a different concept, this is just a function. But anyway, you can just do something like this:

systemd.services.postgresql.postStart =
    let
      extensions = map lib.getName config.services.postgresql.package.installedExtensions;
    in
      ''
        psql dbname << 'EOF'
      ''
      + lib.concatLines (map (e: "CREATE EXTENSION IF NOT EXISTS ${e};") extensions);
      + ''
        EOF
      ''

If that doesn’t work you can manually apply your function to the package set: (config.services.postgresql.extensions config.services.postgresql.package.pkgs).

I suspect this will not be a good idea, but you do you.