Ejemplo n.º 1
0
def test_noop_revision(sql_setup, engine) -> None:
    engine.execute(FUNC.to_sql_statement_create())
    engine.execute(TRIG.to_sql_statement_create())

    register_entities([FUNC, TRIG], entity_types=[PGTrigger])

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "3",
            "message": "do_nothing"
        },
    )
    migration_do_nothing_path = TEST_VERSIONS_ROOT / "3_do_nothing.py"

    with migration_do_nothing_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils" not in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 2
0
def test_update_revision(engine) -> None:
    # Create the view outside of a revision
    engine.execute(TEST_VIEW.to_sql_statement_create())

    # Update definition of TO_UPPER
    UPDATED_TEST_VIEW = PGView(
        TEST_VIEW.schema, TEST_VIEW.signature, """select *, TRUE as is_updated from pg_views"""
    )

    register_entities([UPDATED_TEST_VIEW])

    # Autogenerate a new migration
    # It should detect the change we made and produce a "replace_function" statement
    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={"autogenerate": True, "rev_id": "2", "message": "replace"},
    )

    migration_replace_path = TEST_VERSIONS_ROOT / "2_replace.py"

    with migration_replace_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.replace_entity" in migration_contents
    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "from alembic_utils.pg_view import PGView" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine, command="upgrade", command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine, command="downgrade", command_kwargs={"revision": "base"})
Ejemplo n.º 3
0
def test_replace_revision(sql_setup, engine) -> None:
    engine.execute(TEST_GRANT.to_sql_statement_create())

    UPDATED_GRANT = PGGrantTable(
        schema="public",
        table="account",
        columns=["id"],
        role="anon_user",
        grant=Grant.SELECT,
        with_grant_option=True,
    )

    register_entities([UPDATED_GRANT], entity_types=[PGGrantTable])
    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={"autogenerate": True, "rev_id": "2", "message": "update"},
    )

    migration_create_path = TEST_VERSIONS_ROOT / "2_update.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    # Granting can not be done in place.
    assert "op.replace_entity" in migration_contents
    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "from alembic_utils.pg_grant_table import PGGrantTable" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine, command="upgrade", command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine, command="downgrade", command_kwargs={"revision": "base"})
Ejemplo n.º 4
0
def test_create_revision(sql_setup, engine) -> None:
    engine.execute(FUNC.to_sql_statement_create())

    register_entities([FUNC, TRIG], entity_types=[PGTrigger])
    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "create"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity" in migration_contents
    # Make sure #is_constraint flag was populated
    assert "is_constraint" in migration_contents
    assert "op.drop_entity" in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_trigger import PGTrigger" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 5
0
def test_ignores_extension_functions(engine) -> None:
    # Extensions contain functions and don't have local representations
    # Unless they are excluded, every autogenerate migration will produce
    # drop statements for those functions
    try:
        engine.execute("create extension if not exists unaccent;")
        register_entities([], schemas=["public"])
        run_alembic_command(
            engine=engine,
            command="revision",
            command_kwargs={
                "autogenerate": True,
                "rev_id": "1",
                "message": "no_drops"
            },
        )

        migration_create_path = TEST_VERSIONS_ROOT / "1_no_drops.py"

        with migration_create_path.open() as migration_file:
            migration_contents = migration_file.read()

        assert "op.drop_entity" not in migration_contents
    finally:
        engine.execute("drop extension if exists unaccent;")
def test_create_revision(engine) -> None:
    register_entities([TO_FLOAT_FROM_INT, TO_FLOAT_FROM_TEXT],
                      entity_types=[PGFunction])

    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "create"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert migration_contents.count("op.create_entity") == 2
    assert "op.drop_entity" in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_function import PGFunction" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 7
0
def test_drop(sql_setup, engine) -> None:
    # Manually create a SQL function
    engine.execute(FUNC.to_sql_statement_create())
    engine.execute(TRIG.to_sql_statement_create())

    # Register no functions locally
    register_entities([], schemas=["public"], entity_types=[PGTrigger])

    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "drop"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_drop.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.drop_entity" in migration_contents
    assert "op.create_entity" in migration_contents
    assert "from alembic_utils" in migration_contents
    assert migration_contents.index(
        "op.drop_entity") < migration_contents.index("op.create_entity")
Ejemplo n.º 8
0
def test_create_revision(engine) -> None:
    register_entities([TEST_VIEW], entity_types=[PGView])

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "create"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity" in migration_contents
    assert "op.drop_entity" in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_view import PGView" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 9
0
def test_drop_fails_without_cascade(engine) -> None:

    engine.execute(A.to_sql_statement_create())
    engine.execute(B_A.to_sql_statement_create())

    register_entities([B_A], schemas=["DEV"], entity_types=[PGView])

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "drop"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_drop.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.drop_entity" in migration_contents
    assert "op.create_entity" in migration_contents
    assert "from alembic_utils" in migration_contents
    assert migration_contents.index(
        "op.drop_entity") < migration_contents.index("op.create_entity")

    with pytest.raises(InternalError):
        # sqlalchemy.exc.InternalError: (psycopg2.errors.DependentObjectsStillExist) cannot drop view "A_view" because other objects depend on it
        run_alembic_command(engine=engine,
                            command="upgrade",
                            command_kwargs={"revision": "head"})
Ejemplo n.º 10
0
def test_noop_revision(engine) -> None:
    # Create the view outside of a revision
    engine.execute(TEST_VIEW.to_sql_statement_create())

    register_entities([TEST_VIEW])

    # Create a third migration without making changes.
    # This should result in no create, drop or replace statements
    run_alembic_command(engine=engine, command="upgrade", command_kwargs={"revision": "head"})

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={"autogenerate": True, "rev_id": "3", "message": "do_nothing"},
    )
    migration_do_nothing_path = TEST_VERSIONS_ROOT / "3_do_nothing.py"

    with migration_do_nothing_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils" not in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine, command="upgrade", command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine, command="downgrade", command_kwargs={"revision": "base"})
Ejemplo n.º 11
0
def test_update_is_unreachable(engine) -> None:
    # Updates are not possible. The only parameter that may change is
    # schema, and that will result in a drop and create due to schema
    # scoping assumptions made for all other entities

    # Create the view outside of a revision
    engine.execute(TEST_EXT.to_sql_statement_create())

    UPDATED_TEST_EXT = PGExtension("DEV", TEST_EXT.signature)

    register_entities([UPDATED_TEST_EXT], schemas=["public", "DEV"], entity_types=[PGExtension])

    # Autogenerate a new migration
    # It should detect the change we made and produce a "replace_function" statement
    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={"autogenerate": True, "rev_id": "2", "message": "replace"},
    )

    migration_replace_path = TEST_VERSIONS_ROOT / "2_replace.py"

    with migration_replace_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_extension import PGExtension" in migration_contents
Ejemplo n.º 12
0
def test_drop_revision(engine) -> None:

    # Register no functions locally
    register_entities([], schemas=["DEV"])

    # Manually create a SQL function
    engine.execute(TEST_VIEW.to_sql_statement_create())

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={"autogenerate": True, "rev_id": "1", "message": "drop"},
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_drop.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    # import pdb; pdb.set_trace()

    assert "op.drop_entity" in migration_contents
    assert "op.create_entity" in migration_contents
    assert "from alembic_utils" in migration_contents
    assert migration_contents.index("op.drop_entity") < migration_contents.index("op.create_entity")

    # Execute upgrade
    run_alembic_command(engine=engine, command="upgrade", command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine, command="downgrade", command_kwargs={"revision": "base"})
Ejemplo n.º 13
0
def test_migration_create_function(engine) -> None:
    register_entities([TO_UPPER, TO_UPPER], entity_types=[PGFunction])

    with pytest.raises(DuplicateRegistration):
        run_alembic_command(
            engine=engine,
            command="revision",
            command_kwargs={"autogenerate": True, "rev_id": "1", "message": "raise"},
        )
Ejemplo n.º 14
0
def test_plpgsql_colon_esacpe(engine) -> None:
    # PGFunction.__init__ overrides colon escapes for plpgsql
    # because := should not be escaped for sqlalchemy.text
    # if := is escaped, an exception would be raised

    PLPGSQL_FUNC = PGFunction(
        schema="public",
        signature="some_func(some_text text)",
        definition="""
            returns text
            as
            $$
            declare
                copy_o_text text;
            begin
                copy_o_text := some_text;
                return copy_o_text;
            end;
            $$ language plpgsql
            """,
    )

    register_entities([PLPGSQL_FUNC], entity_types=[PGFunction])

    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "create"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity" in migration_contents
    assert "op.drop_entity" in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_function import PGFunction" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
def test_update_revision(engine) -> None:
    engine.execute(TO_FLOAT_FROM_INT.to_sql_statement_create())
    engine.execute(TO_FLOAT_FROM_TEXT.to_sql_statement_create())

    UPDATE = PGFunction(
        schema="public",
        signature="to_float(x integer)",
        definition="""
            returns float
            as
            $$ select x::text::float $$ language SQL;
            """,
    )

    register_entities([UPDATE, TO_FLOAT_FROM_TEXT], entity_types=[PGFunction])

    # Autogenerate a new migration
    # It should detect the change we made and produce a "replace_function" statement
    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "2",
            "message": "replace"
        },
    )

    migration_replace_path = TEST_VERSIONS_ROOT / "2_replace.py"

    with migration_replace_path.open() as migration_file:
        migration_contents = migration_file.read()

    # One up and one down
    assert migration_contents.count("op.replace_entity") == 2
    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "from alembic_utils.pg_function import PGFunction" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})

    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
def test_trig_update_revision(sql_setup, engine) -> None:
    engine.execute(FUNC.to_sql_statement_create())
    engine.execute(TRIG.to_sql_statement_create())

    UPDATED_TRIG = PGTrigger(
        schema="public",
        signature="lower_account_email",
        on_entity="public.account",
        is_constraint=True,
        definition="""
            AFTER INSERT OR UPDATE ON public.account
            FOR EACH ROW EXECUTE PROCEDURE public.downcase_email()
        """,
    )

    register_entities([FUNC, UPDATED_TRIG], entity_types=[PGTrigger])

    # Autogenerate a new migration
    # It should detect the change we made and produce a "replace_function" statement
    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "2",
            "message": "replace"
        },
    )

    migration_replace_path = TEST_VERSIONS_ROOT / "2_replace.py"

    with migration_replace_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.replace_entity" in migration_contents
    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "from alembic_utils.pg_trigger import PGTrigger" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})

    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 17
0
def test_update_revision(engine, schema_setup) -> None:
    # Create the view outside of a revision
    engine.execute(TEST_POLICY.to_sql_statement_create())

    # Update definition of TO_UPPER
    UPDATED_TEST_POLICY = PGPolicy(
        schema=TEST_POLICY.schema,
        signature=TEST_POLICY.signature,
        on_entity=TEST_POLICY.on_entity,
        definition="""
        for update
        to anon_user
        using (true);
        """,
    )

    register_entities([UPDATED_TEST_POLICY], entity_types=[PGPolicy])

    # Autogenerate a new migration
    # It should detect the change we made and produce a "replace_function" statement
    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "2",
            "message": "replace"
        },
    )

    migration_replace_path = TEST_VERSIONS_ROOT / "2_replace.py"

    with migration_replace_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.replace_entity" in migration_contents
    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "from alembic_utils.pg_policy import PGPolicy" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 18
0
def test_migration_create_function(engine, reset: None) -> None:
    register_entities([TO_UPPER])
    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={"autogenerate": True, "rev_id": "1", "message": "create"},
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert migration_contents.count("op.create_entity") == 1
    assert migration_contents.count("op.drop_entity") == 1
    assert migration_contents.count("from alembic_utils") == 1
Ejemplo n.º 19
0
def test_update_revision(engine) -> None:
    engine.execute(TO_UPPER.to_sql_statement_create())

    # Update definition of TO_UPPER
    UPDATED_TO_UPPER = PGFunction(
        TO_UPPER.schema,
        TO_UPPER.signature,
        r'''returns text as
    $$
    select upper(some_text) || 'def'  -- """ \n \\
    $$ language SQL immutable strict;''',
    )

    register_entities([UPDATED_TO_UPPER])

    # Autogenerate a new migration
    # It should detect the change we made and produce a "replace_function" statement
    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "2",
            "message": "replace"
        },
    )

    migration_replace_path = TEST_VERSIONS_ROOT / "2_replace.py"

    with migration_replace_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.replace_entity" in migration_contents
    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "from alembic_utils.pg_function import PGFunction" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})

    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 20
0
def test_attempt_revision_on_unparsable(engine) -> None:
    BROKEN_VIEW = PGView(schema="public",
                         signature="broken_view",
                         definition="NOPE;")
    register_entities([BROKEN_VIEW], entity_types=[PGView])

    # Reraise of psycopg2.errors.SyntaxError
    with pytest.raises(ProgrammingError):
        run_alembic_command(
            engine=engine,
            command="revision",
            command_kwargs={
                "autogenerate": True,
                "rev_id": "1",
                "message": "create"
            },
        )
Ejemplo n.º 21
0
def test_update_create_or_replace_failover_to_drop_add(engine) -> None:
    # Create the view outside of a revision
    engine.execute(TEST_VIEW.to_sql_statement_create())

    # Update definition of TO_UPPER
    # deleted columns from the beginning of the view.
    # this will fail a create or replace statemnt
    # psycopg2.errors.InvalidTableDefinition) cannot drop columns from view
    # and should fail over to drop and then replace (in plpgsql of `create_or_replace_entity` method
    # on pgview

    UPDATED_TEST_VIEW = PGView(TEST_VIEW.schema, TEST_VIEW.signature,
                               """select TRUE as is_updated from pg_views""")

    register_entities([UPDATED_TEST_VIEW], entity_types=[PGView])

    # Autogenerate a new migration
    # It should detect the change we made and produce a "replace_function" statement
    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "2",
            "message": "replace"
        },
    )

    migration_replace_path = TEST_VERSIONS_ROOT / "2_replace.py"

    with migration_replace_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.replace_entity" in migration_contents
    assert "op.create_entity" not in migration_contents
    assert "op.drop_entity" not in migration_contents
    assert "from alembic_utils.pg_view import PGView" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 22
0
def test_drop_fails_with_cascade(engine, sess) -> None:

    engine.execute(A.to_sql_statement_create())
    engine.execute(B_A.to_sql_statement_create())

    register_entities([B_A], schemas=["DEV"], entity_types=[PGView])

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "drop"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_drop.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.drop_entity" in migration_contents
    assert "op.drop_entity(public_a_view)" in migration_contents

    migration_contents = migration_contents.replace(
        "op.drop_entity(public_a_view)",
        "op.drop_entity(public_a_view, cascade=True)")

    with migration_create_path.open("w") as migration_file:
        migration_file.write(migration_contents)

    assert "op.create_entity" in migration_contents
    assert "from alembic_utils" in migration_contents
    assert migration_contents.index(
        "op.drop_entity") < migration_contents.index("op.create_entity")

    # Cascade drops *B_A* and succeeds
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})

    # Make sure the drop ocurred
    all_views = PGView.from_database(sess, "public")
    assert len(all_views) == 0
Ejemplo n.º 23
0
def test_migration_create_function(engine) -> None:
    to_upper1 = to_upper()
    to_upper2 = to_upper()
    register_entities([to_upper1, to_upper2], entity_types=[PGFunction])

    entities = registry.entities()
    assert len(entities) == 1
    assert entities[0] == to_upper2

    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "raise"
        },
    )
Ejemplo n.º 24
0
def test_has_no_parameters(engine) -> None:
    # Error was occuring in drop statement when function had no parameters
    # related to parameter parsing to drop default statements

    SIDE_EFFECT = PGFunction(
        schema="public",
        signature="side_effect()",
        definition="""
            returns integer
            as
            $$ select 1; $$ language SQL;
            """,
    )

    # Register no functions locally
    register_entities([SIDE_EFFECT],
                      schemas=["public"],
                      entity_types=[PGFunction])

    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "no_arguments"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_no_arguments.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.drop_entity" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 25
0
def test_view_contains_colon(engine) -> None:
    TEST_SEMI_VIEW = PGView(
        schema="public",
        signature="sample",
        definition="select ':' as myfield, '1'::int as othi",
    )
    # NOTE: if a definition contains something that looks like a bind parameter e.g. :a
    # an exception is raised. This test confirms that non-bind-parameter usage of colon
    # is a non-issue

    register_entities([TEST_SEMI_VIEW], entity_types=[PGView])

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "create"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity" in migration_contents
    assert "op.drop_entity" in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_view import PGView" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 26
0
def test_create_revision_with_url_w_colon(engine) -> None:
    """Ensure no regression where views escape colons
    More info at: https://github.com/olirice/alembic_utils/issues/58
    """
    url = "https://something/"
    query = f"SELECT concat('{url}', v::text) FROM generate_series(1,2) x(v)"
    some_view = PGView(schema="public", signature="exa", definition=query)
    register_entities([some_view], entity_types=[PGView])

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "create"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert url in migration_contents
    assert "op.create_entity" in migration_contents
    assert "op.drop_entity" in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_view import PGView" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 27
0
def test_create_revision_with_filters(engine) -> None:
    for entity in reflected_entities:
        engine.execute(entity.to_sql_statement_create())
    register_entities(registered_entities)

    run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "filtered_upgrade"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_filtered_upgrade.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity(public_a_view)" in migration_contents
    assert "op.create_entity(public_toupper)" in migration_contents
    assert "op.drop_entity(public_reflected_view)" in migration_contents
    assert "op.drop_entity(public_reflected_toupper)" in migration_contents

    assert not "op.create_entity(public_exclude_obj_view)" in migration_contents
    assert not "op.create_entity(public_exclude_obj_toupper)" in migration_contents
    assert not "op.drop_entity(public_exclude_name_reflected_view)" in migration_contents
    assert not "op.drop_entity(public_exclude_obj_reflected_toupper)" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 28
0
def test_view_contains_semicolon(engine) -> None:
    TEST_SEMI_VIEW = PGView(
        schema="public",
        signature="sample",
        definition="select ':a' as myfield, '1'::int as othi")

    register_entities([TEST_SEMI_VIEW], entity_types=[PGView])

    output = run_alembic_command(
        engine=engine,
        command="revision",
        command_kwargs={
            "autogenerate": True,
            "rev_id": "1",
            "message": "create"
        },
    )

    migration_create_path = TEST_VERSIONS_ROOT / "1_create.py"

    with migration_create_path.open() as migration_file:
        migration_contents = migration_file.read()

    assert "op.create_entity" in migration_contents
    assert "op.drop_entity" in migration_contents
    assert "op.replace_entity" not in migration_contents
    assert "from alembic_utils.pg_view import PGView" in migration_contents

    # Execute upgrade
    run_alembic_command(engine=engine,
                        command="upgrade",
                        command_kwargs={"revision": "head"})
    # Execute Downgrade
    run_alembic_command(engine=engine,
                        command="downgrade",
                        command_kwargs={"revision": "base"})
Ejemplo n.º 29
0
# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)

target_metadata = SQLModel.metadata

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.

# run migration for database custom functions, views, triggers
sql_entities = sql_function_entities() + sql_view_entities(
) + sql_trigger_entities()
register_entities(sql_entities)


def include_object(object, name, type_, reflected, compare_to):
    print(type_)
    if (type_ in ["table", "function", "extension", "trigger", "view"]
            and reflected and compare_to is None):
        return False
    else:
        return True


def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL
Ejemplo n.º 30
0
from flask import current_app

config.set_main_option(
    'sqlalchemy.url',
    str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%'))
target_metadata = current_app.extensions['migrate'].db.metadata

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.

# Registering db functions here
register_entities([
    get_draft_document_number, get_registration_num, searchkey_name_match,
    searchkey_nickname_match, match_individual_name, searchkey_aircraft,
    searchkey_business_name, searchkey_first_name, searchkey_last_name,
    searchkey_mhr, searchkey_vehicle
])


def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.