perseas / Pyrseas

Provides utilities for Postgres database schema versioning.
https://perseas.github.io/
BSD 3-Clause "New" or "Revised" License
395 stars 67 forks source link

ALTER SEQUENCE OWNER comes before CREATE TABLE #228

Closed jdearing-neudesic closed 3 years ago

jdearing-neudesic commented 3 years ago

I created a yaml file via dbtoyaml and it has a schema and two tables like so:

schema mine:
  owner: postgres
  privileges: []
  sequence foo_id_seq:
    cache_value: 1
    data_type: integer
    increment_by: 1
    max_value: 2147483647
    min_value: null
    owner: postgres
    owner_column: id
    owner_table: foo
    start_value: 1
  sequence parent_id_seq:
    cache_value: 1
    data_type: integer
    increment_by: 1
    max_value: 2147483647
    min_value: null
    owner: postgres
    owner_column: id
    owner_table: parent
    start_value: 1
  table foo:
    columns:
    - id:
        identity: always
        not_null: true
        type: integer
    - description:
        not_null: true
        type: character varying(1024)
    - parentid:
        not_null: true
        type: integer
    - score:
        not_null: true
        type: integer
    foreign_keys:
      fk_foo_parent:
        columns:
        - parentid
        references:
          columns:
          - id
          schema: mine
          table: parent
    owner: postgres
    primary_key:
      pk_foo:
        columns:
        - id
    unique_constraints:
      uq_mine_foo_score:
        columns:
        - parentid
        - score
  table parent:
    columns:
    - id:
        identity: always
        not_null: true
        type: integer
    owner: postgres
    primary_key:
      pk_parent:
        columns:
        - id```

When `yamltodb` is run against that yaml and a database with no schema called `mine` the following SQL is produced:

```SQL
CREATE SCHEMA mine;

ALTER SCHEMA mine OWNER TO postgres;

CREATE TABLE mine.foo (
    id integer NOT NULL GENERATED ALWAYS AS IDENTITY (SEQUENCE NAME mine.foo_id_seq    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    MAXVALUE 2147483647
    CACHE 1),
    description character varying(1024) NOT NULL,
    parentid integer NOT NULL,
    score integer NOT NULL);

ALTER TABLE mine.foo OWNER TO postgres;

ALTER SEQUENCE mine.foo_id_seq OWNER TO postgres;

CREATE TABLE mine.parent (
    id integer NOT NULL GENERATED ALWAYS AS IDENTITY (SEQUENCE NAME mine.parent_id_seq    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    MAXVALUE 2147483647
    CACHE 1));

ALTER TABLE mine.parent OWNER TO postgres;

ALTER SEQUENCE mine.parent_id_seq OWNER TO postgres;

ALTER TABLE mine.foo ADD CONSTRAINT pk_foo PRIMARY KEY (id);

ALTER TABLE mine.foo ADD CONSTRAINT uq_mine_foo_score UNIQUE (parentid, score);

ALTER TABLE mine.parent ADD CONSTRAINT pk_parent PRIMARY KEY (id);

ALTER TABLE mine.foo ADD CONSTRAINT fk_foo_parent FOREIGN KEY (parentid) REFERENCES mine.parent (id);

The ALTER SEQUENCE should come AFTER CREATE TABLE or else it wont run.

jmafc commented 3 years ago

I'm sorry, but I'm having a bit of trouble understanding this. The YAML shows a sequence named AnswerChoice_id_seq with an owner table of answerchoice, but this is followed by a table named foo whose PK column id is generated based on a sequence named survey.foo_id_seq. It seems you tried to replace some names but missed a couple? Also, you say the ALTER SEQUENCE should come before CREATE TABLE, but that is exactly what the generated SQL shows.

jdearing-neudesic commented 3 years ago

@jmafc I apologize. I want ALTER SEQUENCE to come AFTER the CREATE TABLE so it will run.

I wat trying to sanitize my actual schema and failed. As such I went and created a new database with a new schema caleld mins and created **actually validated and tested`` YAML and SQL. The issue has been updated.

jdearing-neudesic commented 3 years ago

Wait a second now its producing the alter afterwards. I will close this and reopen if I can produce a complete example where the alter happens out of sequence.