如何获取sqlalchemy中受影响的行数?
我有一个关于Python和sqlalchemy模块的问题。请问在sqlalchemy中,cursor.rowcount
的对应是什么?
5 个回答
Shiplu的分析是完全正确的。
进一步讨论一下,下面是如何使用sqlalchemy在MySQL中显示更新后的行数,而不是匹配到的行数:创建引擎时需要加上一个标志client_flag=0
。
from sqlalchemy import create_engine
engine = create_engine(
'mysql+pymysql://user:password@host:port/db',
connect_args={'client_flag':0}
)
再详细一点,MySQL返回的rowcount
值取决于提供给C-API函数mysql_real_connect()
的CLIENT_FOUND_ROWS
标志,具体可以参考MySQL文档:
对于UPDATE语句,默认情况下,受影响的行数是实际改变的行数。如果在连接到mysqld时给
mysql_real_connect()
指定CLIENT_FOUND_ROWS
标志,那么受影响的行数就是“找到”的行数,也就是WHERE条件匹配的行数。
这个标志的值是2(MySQL常量),在创建engine
时,sqlalchemy会自动添加这个值,具体可以在这里看到。
在connect_args
中的client_flag
值可以用来覆盖这个默认值。
注意:这可能会影响sane_rowcount
的某些功能(这个功能似乎只在ORM中使用) - 在我的情况下,我只使用sqlalchemy的核心部分。在最后一个链接中:
# FOUND_ROWS must be set in CLIENT_FLAGS to enable
# supports_sane_rowcount.
其实,对于Postgres来说,没有办法准确知道这一点。
最接近的就是 rowcount
。但是,rowcount
并不是受影响的行数,而是匹配的行数。你可以看看文档是怎么说的。
这个属性返回的是匹配的行数,这不一定等于实际被修改的行数。例如,一个UPDATE语句,如果设置的值和当前行的值一样,那么这行就没有实际变化。这样的行会被匹配,但不会被修改。在一些支持这两种风格的数据库中,比如MySQL,
rowcount
默认会在所有情况下返回匹配的行数。
所以在以下两种情况下,rowcount
都会报告1
。因为匹配的行数: 1
用
update
语句修改了一行。Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0
执行了相同的
update
语句。Query OK, 0 row affected (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 0
ResultProxy
对象还有一个叫做 rowcount
的属性。