]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
include trigger test for postgresql and correct documentatione example 5548/head
authorRamonWill <ramonwilliams@hotmail.co.uk>
Sun, 30 Aug 2020 12:54:51 +0000 (13:54 +0100)
committerRamonWill <ramonwilliams@hotmail.co.uk>
Sun, 30 Aug 2020 12:54:51 +0000 (13:54 +0100)
doc/build/core/ddl.rst
test/orm/test_defaults.py
test/requirements.py

index 30619a419a24706a1d5c802d9be1816846d72484..9c2fed198dbb593599abf0b32c5c949fce034124 100644 (file)
@@ -59,9 +59,24 @@ the PostgreSQL backend, we could invoke this as::
         Column('data', String(50))
     )
 
+    func = DDL(
+        "CREATE FUNCTION my_func() "
+        "RETURNS TRIGGER AS $$ "
+        "BEGIN "
+        "NEW.data := 'ins'; "
+        "RETURN NEW; "
+        "END; $$ LANGUAGE PLPGSQL"
+    )
+
     trigger = DDL(
         "CREATE TRIGGER dt_ins BEFORE INSERT ON mytable "
-        "FOR EACH ROW BEGIN SET NEW.data='ins'; END"
+        "FOR EACH ROW EXECUTE PROCEDURE my_func();"
+    )
+
+    event.listen(
+        mytable,
+        'after_create',
+        func.execute_if(dialect='postgresql')
     )
 
     event.listen(
@@ -296,5 +311,3 @@ DDL Expression Constructs API
 .. autoclass:: DropSchema
     :members:
     :undoc-members:
-
-
index 39f48bfccfd94feae99d983a60650d2e41046f84..3c08b9b552998f00e4ab7c75db8240ffb4f9bfdb 100644 (file)
@@ -42,6 +42,9 @@ class TriggerDefaultsTest(fixtures.MappedTest):
                 sa.schema.FetchedValue(for_update=True),
             ),
         )
+
+        is_postgresql = testing.db.dialect.name == "postgresql"
+
         for ins in (
             sa.DDL(
                 "CREATE TRIGGER dt_ins AFTER INSERT ON dt "
@@ -61,18 +64,39 @@ class TriggerDefaultsTest(fixtures.MappedTest):
                 "BEGIN "
                 ":NEW.col2 := 'ins'; :NEW.col4 := 'ins'; END;"
             ).execute_if(dialect="oracle"),
+            sa.DDL(
+                "CREATE TRIGGER dt_ins BEFORE INSERT "
+                "ON dt "
+                "FOR EACH ROW "
+                "EXECUTE PROCEDURE my_func_ins();"
+            ).execute_if(dialect="postgresql"),
             sa.DDL(
                 "CREATE TRIGGER dt_ins BEFORE INSERT ON dt "
                 "FOR EACH ROW BEGIN "
                 "SET NEW.col2='ins'; SET NEW.col4='ins'; END"
             ).execute_if(
                 callable_=lambda ddl, target, bind, **kw: bind.engine.name
-                not in ("oracle", "mssql", "sqlite")
+                not in ("oracle", "mssql", "sqlite", "postgresql")
             ),
         ):
-            event.listen(dt, "after_create", ins)
+            if ins.dialect == "postgresql":
+                my_func_ins = sa.DDL(
+                    "CREATE OR REPLACE FUNCTION my_func_ins() "
+                    "RETURNS TRIGGER AS $$ "
+                    "BEGIN "
+                    "NEW.col2 := 'ins'; NEW.col4 := 'ins'; "
+                    "RETURN NEW; "
+                    "END; $$ LANGUAGE PLPGSQL"
+                ).execute_if(dialect="postgresql")
+                event.listen(dt, "after_create", my_func_ins)
 
-        event.listen(dt, "before_drop", sa.DDL("DROP TRIGGER dt_ins"))
+            event.listen(dt, "after_create", ins)
+        if is_postgresql:
+            event.listen(
+                dt, "before_drop", sa.DDL("DROP TRIGGER dt_ins ON dt")
+            )
+        else:
+            event.listen(dt, "before_drop", sa.DDL("DROP TRIGGER dt_ins"))
 
         for up in (
             sa.DDL(
@@ -91,18 +115,37 @@ class TriggerDefaultsTest(fixtures.MappedTest):
                 "FOR EACH ROW BEGIN "
                 ":NEW.col3 := 'up'; :NEW.col4 := 'up'; END;"
             ).execute_if(dialect="oracle"),
+            sa.DDL(
+                "CREATE TRIGGER dt_up BEFORE UPDATE ON dt "
+                "FOR EACH ROW "
+                "EXECUTE PROCEDURE my_func_up();"
+            ).execute_if(dialect="postgresql"),
             sa.DDL(
                 "CREATE TRIGGER dt_up BEFORE UPDATE ON dt "
                 "FOR EACH ROW BEGIN "
                 "SET NEW.col3='up'; SET NEW.col4='up'; END"
             ).execute_if(
                 callable_=lambda ddl, target, bind, **kw: bind.engine.name
-                not in ("oracle", "mssql", "sqlite")
+                not in ("oracle", "mssql", "sqlite", "postgresql")
             ),
         ):
+            if up.dialect == "postgresql":
+                my_func_up = sa.DDL(
+                    "CREATE OR REPLACE FUNCTION my_func_up() "
+                    "RETURNS TRIGGER AS $$ "
+                    "BEGIN "
+                    "NEW.col3 := 'up'; NEW.col4 := 'up'; "
+                    "RETURN NEW; "
+                    "END; $$ LANGUAGE PLPGSQL"
+                ).execute_if(dialect="postgresql")
+                event.listen(dt, "after_create", my_func_up)
+
             event.listen(dt, "after_create", up)
 
-        event.listen(dt, "before_drop", sa.DDL("DROP TRIGGER dt_up"))
+        if is_postgresql:
+            event.listen(dt, "before_drop", sa.DDL("DROP TRIGGER dt_up ON dt"))
+        else:
+            event.listen(dt, "before_drop", sa.DDL("DROP TRIGGER dt_up"))
 
     @classmethod
     def setup_classes(cls):
index 6d4b3dc90c9cf9b723bf49a43aa45fda275ad744..1c2561bbbe495b7f401224b176b1229ce60f5aa9 100644 (file)
@@ -436,11 +436,6 @@ class DefaultRequirements(SuiteRequirements):
                 no_support("mysql", "requires SUPER priv"),
                 no_support("mariadb", "requires SUPER priv"),
                 exclude("mysql", "<", (5, 0, 10), "not supported by database"),
-                # huh?  TODO: implement triggers for PG tests, remove this
-                no_support(
-                    "postgresql",
-                    "PG triggers need to be implemented for tests",
-                ),
             ]
         )