SQLAlchemy 参数绑定失败

2 投票
1 回答
1372 浏览
提问于 2025-04-18 07:37

我正在尝试使用SQLAlchemy对一些复杂的原始SQL进行查询绑定,但似乎命名参数没有正确绑定。当我运行以下代码时出现了错误,而如果我手动编辑SQL字符串来使用设置的值,这段代码就能正常工作:

engine = create_engine('mysql://scott:tiger@localhost/foo')
vals = {
    'tag_id': 1, 
    'interval': 300,
    'start_time': datetime.datetime(2014, 5, 1, 0, 0),
    'end_time': datetime.datetime(2014, 6, 1, 0, 0)
}

sql = """SELECT
                FROM_UNIXTIME( CEIL( UNIX_TIMESTAMP( event_time ) / :interval ) * :interval ) AS pseudo_time,
                AVG( value ) AS average_value
            FROM  `data_point_double`
            WHERE
              (tag_id = :tag_id) AND
              (event_time BETWEEN :start_time AND :end_time)
            GROUP BY CEIL( UNIX_TIMESTAMP( event_time ) /  :interval  ), tag_id"""
result = engine.execute(sql, **vals)

这导致了以下错误:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) (1064, "你的SQL语法有错误;请检查与你的MySQL服务器版本相对应的手册,以获取在':interval ) * :interval ) AS pseudo_time, ...附近使用的正确语法。"

日志似乎表明参数是被传递的:

2014-05-26 23:23:55,506 INFO sqlalchemy.engine.base.Engine SELECT
                FROM_UNIXTIME( CEIL( UNIX_TIMESTAMP( event_time ) / :interval ) * :interval ) AS pseudo_time,
                AVG( value ) AS average_value
            FROM  `data_point_double`
            WHERE
              (tag_id = :tag_id) AND
              (event_time BETWEEN :start_time AND :end_time)
            GROUP BY CEIL( UNIX_TIMESTAMP( event_time ) / :interval ), tag_id
2014-05-26 23:23:55,506 INFO sqlalchemy.engine.base.Engine {'start_time': datetime.datetime(2014, 5, 1, 0, 0), 'interval': 300, 'end_time': datetime.datetime(2014, 6, 1, 0, 0), 'tag_id': 1L}
2014-05-26 23:23:55,506 INFO sqlalchemy.engine.base.Engine ROLLBACK

我使用命名参数的方式正确吗,还是说这是一个更大的问题?我也尝试过使用mysql+mysqldb作为引擎,但这也没有解决问题。

1 个回答

1

就在我准备发这个的时候,我找到了解决办法,使用文本来包裹查询,这样:

result = engine.execute(sql, **vals)

就变成了这样:

from sqlalchemy.sql import text
result = engine.execute(text(sql), **vals)

希望这个错误信息的内容能帮助到其他人找到这个解决方案!

撰写回答