Search code examples
postgresqlsqitch

Database seeding with Sqitch migrations


I have a set of Sqitch migrations that create tables and functions etc. However, I also need to seed my database with a basic data set required by my app.

However, some of the seeds require Ids from seeds created prior. E.g. I have a function to create a Post and a function to a Comment, after I create a Post I then need to create the Comment referencing the Id of the Post.

My post_create function looks like this:

BEGIN;

  CREATE FUNCTION post_create(
    _title TEXT,
    _body TEXT
  )
  RETURNS SETOF post_type
  LANGUAGE plpgsql
  AS $$
    BEGIN
      RETURN QUERY (
        WITH _created_post AS (  
          INSERT INTO "post" (
            "title",
            "body"
            "created_at"
          )
          VALUES (
            _title,
            _body,
            ROUND(EXTRACT(EPOCH FROM now()))
          )
          RETURNING
            *
        )
        SELECT
          *
        FROM
          _created_post
      );
    END;
  $$;

COMMIT;

And my comment_create function looks similar, like this:

BEGIN;

  CREATE FUNCTION comment_create(
    _post_id INTEGER,
    _body TEXT
  )
  RETURNS SETOF comment_type
  LANGUAGE plpgsql
  AS $$
    BEGIN
      RETURN QUERY (
        WITH _created_comment AS (  
          INSERT INTO "comment" (
            "post_id",
            "body"
            "created_at"
          )
          VALUES (
            _post_id,
            _body,
            ROUND(EXTRACT(EPOCH FROM now()))
          )
          RETURNING
            *
        )
        SELECT
          *
        FROM
          _created_comment
      );
    END;
  $$;

COMMIT;

My seeding migration is basically a blank Sqitch migration:

-- Deploy my-app:seeds to pg
-- requires: post_create
-- requires: comment_create

BEGIN;

  -- Create a post and capture the post Id
  -- Create a comment with previously captured post Id

COMMIT;

However, I'm having trouble figuring out the syntax to make this work correctly.

How can I make my Sqitch migration script call functions and use the result as input when calling other functions?


Solution

  • Use an anonymous function?: https://www.postgresql.org/docs/12/sql-do.html

    DO $$
    DECLARE
        post post_type;
    BEGIN
        --Edited to version that Luke created and used.
        SELECT * FROM post_create(...) INTO post;
        PERFORM comment_create(post.id, 'body text');
    END$$;