今天在使用python 庫mysqldb的rawsql的時候遇到一個問題(其實並不是mysqlbean引起的)
cls.raw_sql('update {table} set available_amount=available_amount+%s, update_time=%s ' 'where user_id=%s'.format(table=Points.Meta.table), amount, now, user_id)
這里我在數據庫里面的available_amount字段類型是decimal(16, 2),然后這里更新的時候amount的類型也是decimal,精度同樣是精確到小數點后面兩位。
但是這里有個問題,在mysql下decimal如果跟string類型做加減法 會報出warning。
在很多情況下,我們使用的orm級別在數據庫曝出warning的時候就會中止運行
錯誤復現:
mysql> update temporary set amount = amount+'0.01' where id=1; Query OK, 1 row affected, 1 warning (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 1 mysql> show warnings; +-------+------+---------------------------------------------+ | Level | Code | Message | +-------+------+---------------------------------------------+ | Note | 1265 | Data truncated for column 'amount' at row 1 | +-------+------+---------------------------------------------+ 1 row in set (0.00 sec)
為什么會造成這種情況, 因為嘗試在mysql里面傳遞帶引號的數字符串會被轉成double類型。使用double類型可能會丟失精度在和decimal相加的時候。所以會報出warning
這種情況只會在字符串數 會丟失精度的情況下報出,所以有時候會出現時有時無的報錯信息。
所以避免這種情況的辦法就是讓decimal直接加浮點型,或者直接使用
cast('12.22' as decimal(16, 2))
轉換成一樣的類型,再相加減同樣可以解決這個問題。
希望能對同樣遇到坑的盆友有所幫助。