9

SQLAlchemy でBEFORE INSERTトリガーを作成する必要があります。

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、"SQL 構文にエラーがあります。... 'DELIMITER |\nCREATE TRIGGER set_rank BE... の近くに...")

DELIMITER を間違って使用していると確信しています。このコンテキストで正しい構文は何ですか / 問題を解決するにはどうすればよいですか?

4

1 に答える 1

15

正直なところ、 は必要ありません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>
>>> 
于 2012-05-04T21:13:47.163 に答える