天天看點

python讀取MySQL資料表時,使用ast子產品轉換decimal格式資料的坑概述解決方案evel()與ast.literal_evel()的差別ast子產品的注意事項

目錄

  • 概述
  • 解決方案
  • evel()與ast.literal_evel()的差別
  • ast子產品的注意事項

概述

MySQL中常用的資料格式有tinyint()、int()、float()、double()、decimal() 、varchar、enum()、datetime;小數格式中decimal比較常用,因為更加精确,這裡就以decimal為例。

從MySQL中讀取了一行資料,内容為:

(17479, datetime.datetime(2020, 4, 1, 0, 0), Decimal('23646.00'), Decimal('23646.00'), Decimal('23622.00')

,因為需要通過TCP傳遞給使用者,是以把資料轉換為字元串,使用者端接收到資料後,需要再把字元串還原,還原字元串常用子產品ast,例如:ast.literal_evel(),這裡就遇到坑了,直接使用ast.literal_evel()會報錯,報錯的原因呢,就是Decimal(‘23646.00’)這種格式ast子產品不認識。

解決方案

首先,Decimal 是decimal子產品的一個類,那麼先導入。與ast.literal_evel()類似的功能還有一個evel(),直接使用evel()還原資料就不會出問題,這是為什麼呢?

evel()與ast.literal_evel()的差別

eval()在做資料轉換前并不知道需要轉化的資料是否合法的python資料類型。隻是在調用函數的時候去計算。如果被計算的内容不是合法的python類型就會抛出異常。而ast.literal_evel()會先判斷需要轉換的内容是不是合法的python資料類型,如果是則進行轉換,否則就不進行轉換。是以,平時還是推薦使用ast.literal_eval()

但是遇到了Decimal(‘23646.00’)事件,為省事期間還是直接使用eval()吧。

簡單的示例:

from decimal import *
import pandas
abc = ((17479, datetime.datetime(2020, 4, 1, 0, 0), Decimal('23646.00'), Decimal('23646.00'), Decimal('23622.00'), Decimal('23624.00'), 74, 100, 0),(30029, datetime.datetime(2020, 4, 25, 0, 58), Decimal('23926.00'), Decimal('23948.00'), Decimal('23926.00'), Decimal('23946.00'), 38, 20, 0))
abc = repr(abc)
abc = eval(abc)
print(abc)
           

ast子產品的注意事項

ast官方文檔

ast子產品的比較常用的兩個方法parse和literal_evel,從官方文檔可以看到這兩個方法都有一處警告:足夠複雜或是巨大的字元串可能導緻Python解釋器的崩潰,因為Python的AST編譯器是有棧深限制的。