python - DELIMITER/在 SQLAlchemy 中创建触发器

标签 python mysql sqlalchemy flask

我需要创建一个 BEFORE INSERT trigger在 SQLAlchemy 中:

DELIMITER |
CREATE TRIGGER set_rank BEFORE INSERT ON authors
FOR EACH ROW BEGIN
    IF NEW.rank = 0 THEN
        SET NEW.rank = (SELECT IFNULL(MAX(a.rank),0) + 1
                        FROM authors AS a
                        WHERE a.id = NEW.pub_id);
    END IF;
END |
DELIMITER ;

在 mysql-workbench 中执行代码工作正常,但在我的实际代码中执行时会出现“您的 SQL 语法错误”异常:

from sqlalchemy.sql.expression import text

connection = db.session.connection()
text(..., connection).execute();

运行 SELECT SLEEP(1)CREATE TABLE test (id INT) 甚至 USE some_db 都可以正常工作。

这是我收到的 mysql 错误消息:

(1064, "You have an error in your SQL syntax; ... near 'DELIMITER |\nCREATE TRIGGER set_rank BE...")

我很确定我使用的分隔符不正确。在这个上下文中正确的语法是什么/如何解决我的问题?

最佳答案

您真的不需要DELIMITER。那仅适用于命令行客户端。作为程序员,您将分割语句,因此分隔符将被忽略。

>>> from sqlalchemy import *
>>> 
>>> trigger_text = """
... CREATE TRIGGER set_rank BEFORE INSERT ON authors
... FOR EACH ROW BEGIN
...     IF NEW.rank = 0 THEN
...         SET NEW.rank = (SELECT IFNULL(MAX(a.rank),0) + 1
...                         FROM authors AS a
...                         WHERE a.id = NEW.pub_id);
...     END IF;
... END
... """
>>> 
>>> metadata = MetaData()
>>> authors = Table("authors", metadata,
...     Column("id", Integer, primary_key=True),
...     Column("rank", Integer),
...     Column("pub_id", Integer))
>>> 
>>> engine = create_engine("mysql://root@127.0.0.1/test", echo=True)
>>> authors.create(engine)
2012-05-04 17:11:41,093 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE authors (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    rank INTEGER, 
    pub_id INTEGER, 
    PRIMARY KEY (id)
)


2012-05-04 17:11:41,093 INFO sqlalchemy.engine.base.Engine ()
2012-05-04 17:10:51,376 INFO sqlalchemy.engine.base.Engine COMMIT
>>> engine.execute(trigger_text)
2012-05-04 17:11:41,159 INFO sqlalchemy.engine.base.Engine 
CREATE TRIGGER set_rank BEFORE INSERT ON authors
FOR EACH ROW BEGIN
    IF NEW.rank = 0 THEN
        SET NEW.rank = (SELECT IFNULL(MAX(a.rank),0) + 1
                        FROM authors AS a
                        WHERE a.id = NEW.pub_id);
    END IF;
END

2012-05-04 17:11:41,159 INFO sqlalchemy.engine.base.Engine ()
2012-05-04 17:11:41,312 INFO sqlalchemy.engine.base.Engine COMMIT
<sqlalchemy.engine.base.ResultProxy object at 0x2be1ed0>
>>> 

关于python - DELIMITER/在 SQLAlchemy 中创建触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10455547/

相关文章:

php - 使用 MySQL/PHP 修改 SELECT 返回的值

python - 如何将 SQL 中的 RAISERROR 转换为 Python Pandas/SQLAlchemy

python - Sqlalchemy 真实总和

python - python 中是否有 chgrp -R 的等效项?

php - 使用 PDO 和 bootstrap 向现有 html 表添加新行

python - 如何使类属性不可变?

php - 选择除查询中两个表中匹配的行之外的所有行

python - SQLAlchemy 中带计数的子查询

python - 平滑绘制数据框的所有列

python - 使用 django 强制执行唯一的上传文件名?