Python中操作MySQL數(shù)據(jù)庫時如何處理數(shù)據(jù)類型轉(zhuǎn)換問題
一、先搞懂:Python 與 MySQL 數(shù)據(jù)類型的默認(rèn)映射
pymysql會自動完成基礎(chǔ)類型的轉(zhuǎn)換,你先記住核心映射規(guī)則,大部分場景不用手動處理:
| MySQL 數(shù)據(jù)類型 | Python 類型 | 說明 |
|---|---|---|
| INT/TINYINT/BIGINT | int | 整數(shù)類型直接映射 |
| FLOAT/DOUBLE/DECIMAL | float/Decimal | DECIMAL 默認(rèn)轉(zhuǎn) float(需精準(zhǔn)則手動轉(zhuǎn)) |
| VARCHAR/TEXT | str | 字符串自動轉(zhuǎn) Unicode |
| DATE/DATETIME/TIMESTAMP | datetime.datetime | 日期時間自動轉(zhuǎn) datetime 對象 |
| BOOLEAN | bool | MySQL 的 BOOL 本質(zhì)是 TINYINT (1) |
| NULL | None | 空值對應(yīng) Python 的 None |
| BLOB | bytes | 二進(jìn)制數(shù)據(jù)轉(zhuǎn) bytes |
二、手動處理數(shù)據(jù)類型轉(zhuǎn)換的場景與示例
自動轉(zhuǎn)換滿足 80% 的場景,但遇到精度要求高、格式自定義、特殊類型時,需要手動干預(yù),以下是高頻場景:
1. 場景 1:DECIMAL 類型(金額 / 精度數(shù)據(jù))避免浮點(diǎn)誤差
MySQL 的 DECIMAL 用于存儲金額、匯率等精準(zhǔn)數(shù)值,pymysql默認(rèn)轉(zhuǎn) float 會丟失精度,需手動轉(zhuǎn)decimal.Decimal:
import pymysql
from decimal import Decimal
# 1. 連接時指定轉(zhuǎn)換規(guī)則(推薦)
config = {
'host': 'localhost',
'user': 'root',
'password': '你的密碼',
'database': 'test_db',
'conv': pymysql.converters.conversions.copy() # 復(fù)制默認(rèn)轉(zhuǎn)換規(guī)則
}
# 重寫DECIMAL轉(zhuǎn)換規(guī)則:轉(zhuǎn)Decimal而非float
config['conv'][pymysql.FIELD_TYPE.DECIMAL] = Decimal
config['conv'][pymysql.FIELD_TYPE.NEWDECIMAL] = Decimal
# 2. 連接并查詢
connection = pymysql.connect(**config)
cursor = connection.cursor(pymysql.cursors.DictCursor)
# 創(chuàng)建測試表(含DECIMAL字段)
cursor.execute("""
CREATE TABLE IF NOT EXISTS order_info (
id INT AUTO_INCREMENT PRIMARY KEY,
order_no VARCHAR(20),
amount DECIMAL(10,2) # 金額,10位總長度,2位小數(shù)
)
""")
# 插入數(shù)據(jù)(直接傳Decimal更精準(zhǔn))
cursor.execute("INSERT INTO order_info (order_no, amount) VALUES (%s, %s)",
("ORD202501", Decimal("99.99")))
connection.commit()
# 查詢驗證(amount直接是Decimal類型)
cursor.execute("SELECT * FROM order_info WHERE id = %s", (1,))
result = cursor.fetchone()
print(f"金額:{result['amount']},類型:{type(result['amount'])}") # 輸出:99.99,類型:<class 'decimal.Decimal'>
cursor.close()
connection.close()
2. 場景 2:日期時間類型的自定義格式轉(zhuǎn)換
MySQL 的 DATETIME 自動轉(zhuǎn)datetime.datetime,但有時需要轉(zhuǎn)字符串(如接口返回)或自定義格式:
import pymysql
from datetime import datetime
connection = pymysql.connect(
host='localhost',
user='root',
password='你的密碼',
database='test_db',
cursorclass=pymysql.cursors.DictCursor
)
cursor = connection.cursor()
# 1. 寫入:Python datetime對象直接傳入(自動轉(zhuǎn)MySQL DATETIME)
insert_time = datetime(2025, 1, 19, 10, 30, 0)
cursor.execute("INSERT INTO users (name, create_time) VALUES (%s, %s)",
("王五", insert_time))
connection.commit()
# 2. 讀?。篸atetime對象轉(zhuǎn)自定義格式字符串
cursor.execute("SELECT create_time FROM users WHERE name = %s", ("王五",))
result = cursor.fetchone()
dt_obj = result['create_time']
# 轉(zhuǎn)成"YYYY-MM-DD HH:MM:SS"字符串
dt_str = dt_obj.strftime("%Y-%m-%d %H:%M:%S")
print(f"創(chuàng)建時間:{dt_str},類型:{type(dt_str)}") # 輸出:2025-01-19 10:30:00,類型:str
# 3. 反向:字符串轉(zhuǎn)datetime寫入
dt_str2 = "2025-01-20 15:00:00"
dt_obj2 = datetime.strptime(dt_str2, "%Y-%m-%d %H:%M:%S")
cursor.execute("UPDATE users SET create_time = %s WHERE name = %s",
(dt_obj2, "王五"))
connection.commit()
cursor.close()
connection.close()
3. 場景 3:JSON 類型的處理(MySQL 5.7 + 支持)
MySQL 的 JSON 類型需手動序列化 / 反序列化(pymysql不會自動轉(zhuǎn) Python 字典):
import pymysql
import json
connection = pymysql.connect(
host='localhost',
user='root',
password='你的密碼',
database='test_db',
cursorclass=pymysql.cursors.DictCursor
)
cursor = connection.cursor()
# 1. 創(chuàng)建含JSON字段的表
cursor.execute("""
CREATE TABLE IF NOT EXISTS user_profile (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
profile JSON # JSON類型字段
)
""")
# 2. 寫入:Python字典轉(zhuǎn)JSON字符串
profile_dict = {"hobby": ["籃球", "編程"], "address": {"city": "北京"}}
profile_json = json.dumps(profile_dict, ensure_ascii=False) # ensure_ascii=False保留中文
cursor.execute("INSERT INTO user_profile (user_id, profile) VALUES (%s, %s)",
(1, profile_json))
connection.commit()
# 3. 讀?。篔SON字符串轉(zhuǎn)Python字典
cursor.execute("SELECT profile FROM user_profile WHERE user_id = %s", (1,))
result = cursor.fetchone()
profile_str = result['profile']
profile_dict2 = json.loads(profile_str)
print(f"愛好:{profile_dict2['hobby']},城市:{profile_dict2['address']['city']}")
# 輸出:愛好:['籃球', '編程'],城市:北京
cursor.close()
connection.close()
4. 場景 4:BLOB / 二進(jìn)制數(shù)據(jù)(如圖片、文件)
MySQL 的 BLOB 類型對應(yīng) Python 的 bytes,讀寫時需處理二進(jìn)制數(shù)據(jù):
import pymysql
connection = pymysql.connect(
host='localhost',
user='root',
password='你的密碼',
database='test_db',
cursorclass=pymysql.cursors.DictCursor
)
cursor = connection.cursor()
# 1. 創(chuàng)建含BLOB字段的表
cursor.execute("""
CREATE TABLE IF NOT EXISTS file_store (
id INT AUTO_INCREMENT PRIMARY KEY,
file_name VARCHAR(100),
file_data BLOB # 二進(jìn)制數(shù)據(jù)字段
)
""")
# 2. 寫入:讀取文件轉(zhuǎn)bytes寫入
with open("test.jpg", "rb") as f:
file_bytes = f.read()
cursor.execute("INSERT INTO file_store (file_name, file_data) VALUES (%s, %s)",
("test.jpg", file_bytes))
connection.commit()
# 3. 讀取:bytes寫入文件
cursor.execute("SELECT file_data FROM file_store WHERE file_name = %s", ("test.jpg",))
result = cursor.fetchone()
file_bytes2 = result['file_data']
with open("test_copy.jpg", "wb") as f:
f.write(file_bytes2)
print("文件已保存為test_copy.jpg")
cursor.close()
connection.close()
三、避坑要點(diǎn)
- 避免手動拼接類型轉(zhuǎn)換:不要用
str(數(shù)值)拼接 SQL,始終用%s參數(shù)占位符,pymysql會自動處理類型映射; - 空值處理:MySQL 的 NULL 對應(yīng) Python 的 None,寫入時直接傳 None,讀取時判斷是否為 None 避免報錯;
- 編碼問題:字符串類型(VARCHAR/TEXT)確保連接時指定
charset='utf8mb4',避免中文 / 特殊字符轉(zhuǎn)碼錯誤; - 超大整數(shù)處理:MySQL 的 BIGINT 如果超過 Python int 范圍(如大于 2^63-1),需用
pymysql的long轉(zhuǎn)換(Python 3 已統(tǒng)一為 int,無需額外處理)。
總結(jié)
- 基礎(chǔ)類型:
pymysql自動完成 int/str/bool/None 等類型映射,無需手動處理; - 高精度 / 特殊類型:DECIMAL 轉(zhuǎn)
decimal.Decimal、JSON 用json模塊序列化、BLOB 用 bytes 處理; - 日期時間:利用
datetime模塊完成對象與字符串的互轉(zhuǎn),寫入時直接傳 datetime 對象更安全; - 核心原則:優(yōu)先用參數(shù)化查詢(% s),避免手動類型拼接,防止轉(zhuǎn)換錯誤和 SQL 注入。
到此這篇關(guān)于Python中操作MySQL數(shù)據(jù)庫時如何處理數(shù)據(jù)類型轉(zhuǎn)換問題的文章就介紹到這了,更多相關(guān)Python操作MySQL數(shù)據(jù)類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python從內(nèi)存地址上加載python對象過程詳解
這篇文章主要介紹了python從內(nèi)存地址上加載pythn對象過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01
Python中的set可變集合與frozenset不可變集合的終極指南
這篇文章主要為大家詳細(xì)介紹了Python中set與frozenset的區(qū)別與應(yīng)用,set是可變集合,支持增刪元素和自動去重,frozenset是不可變集合,下面小編就來和大家詳細(xì)介紹一下吧2026-02-02
python實現(xiàn)對指定輸入的字符串逆序輸出的6種方法
這篇文章主要介紹了python實現(xiàn)對指定輸入的字符串逆序輸出的6種方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
python實現(xiàn)sm2和sm4國密(國家商用密碼)算法的示例
這篇文章主要介紹了python實現(xiàn)sm2和sm4國密(國家商用密碼)算法的示例,幫助大家使用python加密文件,感興趣的朋友可以了解下2020-09-09
Python網(wǎng)絡(luò)編程之ZeroMQ知識總結(jié)
這篇文章主要介紹了Python網(wǎng)絡(luò)編程之ZeroMQ知識總結(jié),文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
Python爬蟲獲取國外大橋排行榜數(shù)據(jù)清單
這篇文章主要介紹了Python爬蟲獲取國外大橋排行榜數(shù)據(jù)清單,文章通過PyQuery?解析框架展開全文詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-05-05
Python內(nèi)存管理機(jī)制之垃圾回收與引用計數(shù)操作全過程
SQLAlchemy是Python中最流行的ORM(對象關(guān)系映射)框架之一,它提供了高效且靈活的數(shù)據(jù)庫操作方式,本文將介紹如何使用SQLAlchemy?ORM進(jìn)行數(shù)據(jù)庫操作,感興趣的朋友跟隨小編一起看看吧2025-09-09

