最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中數(shù)據(jù)庫操作庫實戰(zhàn)示例

 更新時間:2026年02月26日 09:09:38   作者:小小測試開發(fā)  
本文將詳細介紹Python中最主流、最實用的數(shù)據(jù)庫操作庫,涵蓋關系型數(shù)據(jù)庫(MySQL、PostgreSQL、SQLite)和非關系型數(shù)據(jù)庫(MongoDB、Redis)對應的操作庫,感興趣的朋友跟隨小編一起看看吧

在Python開發(fā)中,數(shù)據(jù)庫操作是高頻需求,無論是Web開發(fā)、數(shù)據(jù)分析、自動化測試,還是后臺服務,都需要通過代碼與數(shù)據(jù)庫交互(增刪改查、連接管理等)。Python生態(tài)中提供了豐富的數(shù)據(jù)庫操作庫,不同庫適配不同數(shù)據(jù)庫類型、場景需求,各有優(yōu)劣。

本文將詳細介紹Python中最主流、最實用的數(shù)據(jù)庫操作庫,涵蓋關系型數(shù)據(jù)庫(MySQL、PostgreSQL、SQLite)和非關系型數(shù)據(jù)庫(MongoDB、Redis)對應的操作庫,每個庫均包含「庫介紹→安裝步驟→核心用法→實戰(zhàn)示例→注意事項」,兼顧初學者入門和開發(fā)者實戰(zhàn)復用,全程貼合Markdown排版,結構清晰、內容詳實。

注:所有示例均基于Python 3.8+版本,代碼可直接復制運行(需提前安裝對應庫、配置數(shù)據(jù)庫環(huán)境);重點講解“通用操作邏輯”,避免冗余,同時補充生產環(huán)境必備的異常處理、連接池等技巧。

一、前言:Python數(shù)據(jù)庫操作的核心邏輯

無論使用哪種數(shù)據(jù)庫、哪個操作庫,Python與數(shù)據(jù)庫交互的核心邏輯一致,可概括為4步,統(tǒng)一梳理如下,后續(xù)所有庫的示例均遵循此邏輯:

  • 連接數(shù)據(jù)庫:通過庫提供的API,傳入數(shù)據(jù)庫地址、端口、用戶名、密碼、數(shù)據(jù)庫名等參數(shù),建立與數(shù)據(jù)庫的連接(關鍵:連接需及時關閉,避免資源泄露);
  • 創(chuàng)建操作對象:通過連接對象,創(chuàng)建游標(cursor)或會話(session),用于執(zhí)行SQL語句或數(shù)據(jù)庫命令;
  • 執(zhí)行操作:通過操作對象執(zhí)行增刪改查、建表等操作,獲取執(zhí)行結果(查詢操作返回數(shù)據(jù),增刪改返回影響行數(shù));
  • 關閉資源:操作完成后,先關閉操作對象(游標/會話),再關閉數(shù)據(jù)庫連接,順序不可顛倒。

補充:生產環(huán)境中,不建議頻繁創(chuàng)建/關閉連接(耗時且耗資源),優(yōu)先使用「連接池」管理連接;同時需添加異常處理,避免因數(shù)據(jù)庫異常(如連接失敗、SQL錯誤)導致程序崩潰。

二、關系型數(shù)據(jù)庫操作庫(重點)

關系型數(shù)據(jù)庫(MySQL、PostgreSQL、SQLite)是最常用的數(shù)據(jù)庫類型,特點是數(shù)據(jù)結構化、支持SQL語句、事務安全。Python中對應操作庫均遵循“連接→操作→關閉”的邏輯,以下重點講解3個主流庫。

1. MySQLdb / PyMySQL(適配MySQL數(shù)據(jù)庫)

MySQL是Python開發(fā)中最常用的關系型數(shù)據(jù)庫,對應的操作庫有兩個:MySQLdbPyMySQL,兩者功能一致、用法幾乎相同,核心區(qū)別在于:MySQLdb僅支持Python 2.x,且僅支持Windows系統(tǒng);PyMySQL支持Python 3.x,跨平臺(Windows、Linux、Mac),是目前的首選。

本文重點講解 PyMySQL(主流、通用),替代過時的MySQLdb。

(1)庫介紹

  • 定位:純Python編寫的MySQL客戶端庫,無需依賴C語言擴展,安裝簡單、跨平臺;
  • 核心功能:支持MySQL 5.5+版本,實現(xiàn)MySQL所有核心操作(增刪改查、事務、存儲過程、批量操作等);
  • 優(yōu)勢:輕量、易用、兼容性好,與MySQLdb API完全兼容,可無縫替換;
  • 劣勢:執(zhí)行效率略低于依賴C擴展的庫(如mysql-connector-python),但足以滿足絕大多數(shù)場景。

(2)安裝步驟

使用pip命令安裝,直接執(zhí)行以下命令(無需額外依賴):

# 安裝PyMySQL(推薦)
pip install pymysql
# 若需安裝MySQLdb(僅Python 2.x,不推薦)
# pip install mysqldb

(3)核心用法與實戰(zhàn)示例

示例場景:連接本地MySQL數(shù)據(jù)庫(數(shù)據(jù)庫名:test_db,用戶名:root,密碼:123456),實現(xiàn)「建表→插入數(shù)據(jù)→查詢數(shù)據(jù)→更新數(shù)據(jù)→刪除數(shù)據(jù)」的完整操作,包含異常處理和連接關閉。

import pymysql
from pymysql import Error
def mysql_demo():
    # 1. 數(shù)據(jù)庫連接參數(shù)(根據(jù)實際環(huán)境修改)
    db_config = {
        "host": "localhost",  # 數(shù)據(jù)庫地址(本地為localhost)
        "port": 3306,         # 數(shù)據(jù)庫端口(MySQL默認3306)
        "user": "root",       # 用戶名
        "password": "123456", # 密碼
        "database": "test_db" # 要連接的數(shù)據(jù)庫名
    }
    # 初始化連接和游標
    connection = None
    cursor = None
    try:
        # 2. 建立數(shù)據(jù)庫連接
        connection = pymysql.connect(**db_config)
        if connection.open:
            print("? 成功連接到MySQL數(shù)據(jù)庫")
        # 3. 創(chuàng)建游標對象(用于執(zhí)行SQL語句)
        cursor = connection.cursor()
        # 4. 執(zhí)行操作(建表→插入→查詢→更新→刪除)
        # 4.1 建表(若表不存在)
        create_table_sql = """
        CREATE TABLE IF NOT EXISTS user_info (
            id INT AUTO_INCREMENT PRIMARY KEY,  # 自增主鍵
            name VARCHAR(50) NOT NULL,         # 姓名(非空)
            age INT,                           # 年齡
            gender VARCHAR(10),                # 性別
            create_time DATETIME DEFAULT CURRENT_TIMESTAMP  # 創(chuàng)建時間(默認當前時間)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
        """
        cursor.execute(create_table_sql)
        print("? 表創(chuàng)建成功(若不存在)")
        # 4.2 插入數(shù)據(jù)(單條插入)
        insert_sql = "INSERT INTO user_info (name, age, gender) VALUES (%s, %s, %s)"
        insert_data = ("張三", 25, "男")  # 占位符%s,避免SQL注入(重點?。?
        cursor.execute(insert_sql, insert_data)
        connection.commit()  # 插入/更新/刪除操作需提交事務
        print(f"? 插入數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
        # 4.3 批量插入數(shù)據(jù)(效率高于單條插入)
        batch_insert_sql = "INSERT INTO user_info (name, age, gender) VALUES (%s, %s, %s)"
        batch_data = [("李四", 28, "男"), ("王五", 23, "女"), ("趙六", 30, "男")]
        cursor.executemany(batch_insert_sql, batch_data)
        connection.commit()
        print(f"? 批量插入數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
        # 4.4 查詢數(shù)據(jù)(單條查詢+多條查詢)
        # 單條查詢(根據(jù)id查詢)
        select_one_sql = "SELECT * FROM user_info WHERE id = %s"
        cursor.execute(select_one_sql, (1,))  # 注意:參數(shù)需是元組,即使只有一個值
        result_one = cursor.fetchone()  # 獲取單條結果(返回元組,無結果返回None)
        print(f"? 單條查詢結果:{result_one}")
        # 多條查詢(查詢所有數(shù)據(jù))
        select_all_sql = "SELECT * FROM user_info"
        cursor.execute(select_all_sql)
        result_all = cursor.fetchall()  # 獲取所有結果(返回列表,每個元素是元組)
        print(f"? 所有查詢結果(共{len(result_all)}條):")
        for row in result_all:
            print(f"id: {row[0]}, 姓名: {row[1]}, 年齡: {row[2]}, 性別: {row[3]}, 創(chuàng)建時間: {row[4]}")
        # 4.5 更新數(shù)據(jù)
        update_sql = "UPDATE user_info SET age = %s WHERE name = %s"
        update_data = (26, "張三")
        cursor.execute(update_sql, update_data)
        connection.commit()
        print(f"? 更新數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
        # 4.6 刪除數(shù)據(jù)
        delete_sql = "DELETE FROM user_info WHERE name = %s"
        delete_data = ("趙六",)
        cursor.execute(delete_sql, delete_data)
        connection.commit()
        print(f"? 刪除數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
    except Error as e:
        # 異常處理(捕獲連接、SQL執(zhí)行等異常)
        print(f"? 數(shù)據(jù)庫操作異常:{e}")
        # 若有事務未提交,回滾(避免數(shù)據(jù)錯亂)
        if connection:
            connection.rollback()
    finally:
        # 5. 關閉資源(先關游標,再關連接,順序不可顛倒)
        if cursor:
            cursor.close()
            print("? 游標已關閉")
        if connection and connection.open:
            connection.close()
            print("? 數(shù)據(jù)庫連接已關閉")
# 執(zhí)行示例
if __name__ == "__main__":
    mysql_demo()

(4)關鍵注意事項

  • 避免SQL注入:必須使用占位符 %s 傳遞參數(shù),不可直接拼接SQL字符串(如 "INSERT INTO user_info VALUES ('" + name + "')"),否則會導致SQL注入漏洞;
  • 事務管理:插入、更新、刪除操作必須執(zhí)行 connection.commit() 提交事務,異常時需執(zhí)行 connection.rollback() 回滾,避免數(shù)據(jù)錯亂;
  • 連接關閉:務必在finally塊中關閉游標和連接,確保即使出現(xiàn)異常,資源也能正常釋放;
  • 編碼設置:創(chuàng)建表時指定 CHARSET=utf8mb4,支持中文和特殊字符(如emoji),避免中文亂碼;
  • 連接池優(yōu)化:生產環(huán)境中,頻繁創(chuàng)建/關閉連接會影響效率,可使用 DBUtils 庫實現(xiàn)連接池(后續(xù)補充)。

2. sqlite3(適配SQLite數(shù)據(jù)庫,Python內置)

SQLite是一款「輕量級嵌入式關系型數(shù)據(jù)庫」,無需單獨安裝數(shù)據(jù)庫服務,數(shù)據(jù)存儲在單個文件中,適合小型項目、本地測試、嵌入式開發(fā)等場景。Python內置 sqlite3 庫,無需額外安裝,可直接使用。

(1)庫介紹

  • 定位:Python標準庫(3.0+版本內置),無需安裝,開箱即用;
  • 核心功能:支持SQLite所有核心操作,適配SQLite 3.x版本,支持事務、觸發(fā)器、視圖等;
  • 優(yōu)勢:輕量、無需部署、零配置、跨平臺,單個數(shù)據(jù)庫文件可直接遷移;
  • 劣勢:不適合高并發(fā)、大數(shù)據(jù)量場景(性能有限),不支持多線程同時寫入。

(2)安裝步驟

無需安裝!Python 3.0+版本默認內置,直接導入 sqlite3 即可使用。

(3)核心用法與實戰(zhàn)示例

示例場景:創(chuàng)建本地SQLite數(shù)據(jù)庫文件(test_sqlite.db),實現(xiàn)「建表→插入→查詢→更新→刪除」完整操作,貼合SQLite輕量特性,補充異常處理。

import sqlite3
from sqlite3 import Error
def sqlite_demo():
    # 1. 數(shù)據(jù)庫連接參數(shù)(SQLite無需用戶名密碼,僅需指定數(shù)據(jù)庫文件路徑)
    db_path = "test_sqlite.db"  # 數(shù)據(jù)庫文件存儲路徑(不存在則自動創(chuàng)建)
    # 初始化連接和游標
    connection = None
    cursor = None
    try:
        # 2. 建立數(shù)據(jù)庫連接(SQLite連接是文件連接,不存在則創(chuàng)建文件)
        connection = sqlite3.connect(db_path)
        print("? 成功連接到SQLite數(shù)據(jù)庫(文件:test_sqlite.db)")
        # 3. 創(chuàng)建游標對象
        cursor = connection.cursor()
        # 4. 執(zhí)行操作(建表→插入→查詢→更新→刪除)
        # 4.1 建表(若表不存在)
        create_table_sql = """
        CREATE TABLE IF NOT EXISTS book_info (
            id INTEGER PRIMARY KEY AUTOINCREMENT,  # SQLite自增用INTEGER,而非INT
            book_name TEXT NOT NULL,               # 書名(非空)
            author TEXT,                           # 作者
            price REAL,                            # 價格(浮點型)
            publish_time TEXT                      # 出版時間(字符串格式)
        );
        """
        cursor.execute(create_table_sql)
        print("? 表創(chuàng)建成功(若不存在)")
        # 4.2 插入數(shù)據(jù)(單條+批量)
        # 單條插入
        insert_sql = "INSERT INTO book_info (book_name, author, price, publish_time) VALUES (?, ?, ?, ?)"
        # SQLite占位符用?,而非%s,注意區(qū)別!
        insert_data = ("Python編程:從入門到精通", "張三", 89.9, "2023-01-01")
        cursor.execute(insert_sql, insert_data)
        # 批量插入
        batch_data = [
            ("Java編程思想", "李四", 99.9, "2022-05-01"),
            ("SQL必知必會", "王五", 59.9, "2023-03-15"),
            ("Redis實戰(zhàn)", "趙六", 79.9, "2023-06-20")
        ]
        cursor.executemany(insert_sql, batch_data)
        connection.commit()  # SQLite同樣需要提交事務
        print(f"? 插入數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
        # 4.3 查詢數(shù)據(jù)
        # 單條查詢(根據(jù)id)
        select_one_sql = "SELECT * FROM book_info WHERE id = ?"
        cursor.execute(select_one_sql, (1,))
        result_one = cursor.fetchone()
        print(f"? 單條查詢結果:{result_one}")
        # 多條查詢(查詢價格>60的書籍)
        select_condition_sql = "SELECT book_name, author, price FROM book_info WHERE price > ?"
        cursor.execute(select_condition_sql, (60,))
        result_condition = cursor.fetchall()
        print(f"? 價格>60的書籍(共{len(result_condition)}條):")
        for row in result_condition:
            print(f"書名: {row[0]}, 作者: {row[1]}, 價格: {row[2]}元")
        # 4.4 更新數(shù)據(jù)
        update_sql = "UPDATE book_info SET price = ? WHERE book_name = ?"
        update_data = (79.9, "Python編程:從入門到精通")
        cursor.execute(update_sql, update_data)
        connection.commit()
        print(f"? 更新數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
        # 4.5 刪除數(shù)據(jù)
        delete_sql = "DELETE FROM book_info WHERE author = ?"
        delete_data = ("趙六",)
        cursor.execute(delete_sql, delete_data)
        connection.commit()
        print(f"? 刪除數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
    except Error as e:
        print(f"? 數(shù)據(jù)庫操作異常:{e}")
        if connection:
            connection.rollback()
    finally:
        # 關閉資源
        if cursor:
            cursor.close()
            print("? 游標已關閉")
        if connection:
            connection.close()
            print("? 數(shù)據(jù)庫連接已關閉")
# 執(zhí)行示例
if __name__ == "__main__":
    sqlite_demo()

(4)關鍵注意事項

  • 占位符差異:SQLite的占位符是 ?,而非PyMySQL的 %s,這是最容易出錯的點,務必注意;
  • 自增字段:SQLite的自增字段需定義為 INTEGER PRIMARY KEY AUTOINCREMENT,而非MySQL的INT AUTO_INCREMENT
  • 數(shù)據(jù)類型:SQLite支持的數(shù)據(jù)類型較少,常用 TEXT(字符串)、INTEGER(整數(shù))、REAL(浮點),無需嚴格匹配類型(如字符串可存入整數(shù));
  • 并發(fā)限制:SQLite不支持多線程同時寫入,高并發(fā)場景需避免使用,優(yōu)先選擇MySQL;
  • 文件路徑:若指定的數(shù)據(jù)庫文件路徑不存在,SQLite會自動創(chuàng)建該文件(無需手動創(chuàng)建),推薦使用絕對路徑,避免路徑錯亂。

3. psycopg2(適配PostgreSQL數(shù)據(jù)庫)

PostgreSQL是一款功能強大、開源免費的關系型數(shù)據(jù)庫,支持復雜查詢、JSON數(shù)據(jù)類型、事務安全,適合中大型項目、數(shù)據(jù)分析場景。Python中操作PostgreSQL的主流庫是 psycopg2(依賴C擴展,效率高)和 psycopg2-binary(二進制版本,安裝簡單,無需編譯)。

(1)庫介紹

  • 定位:PostgreSQL官方推薦的Python客戶端庫,功能完整、執(zhí)行效率高;
  • 核心功能:支持PostgreSQL所有特性(復雜查詢、JSON、事務、存儲過程、批量操作等),適配PostgreSQL 9.0+版本;
  • 優(yōu)勢:效率高、兼容性好,支持異步操作(psycopg2-async),適合中大型項目;
  • 劣勢:安裝時需依賴PostgreSQL的開發(fā)環(huán)境(編譯版本),推薦使用二進制版本 psycopg2-binary 簡化安裝。

(2)安裝步驟

推薦安裝二進制版本(無需編譯,跨平臺),執(zhí)行以下命令:

# 安裝psycopg2二進制版本(推薦)
pip install psycopg2-binary
# 安裝編譯版本(需提前安裝PostgreSQL開發(fā)環(huán)境,不推薦)
# pip install psycopg2

(3)核心用法與實戰(zhàn)示例

示例場景:連接本地PostgreSQL數(shù)據(jù)庫(數(shù)據(jù)庫名:test_pg,用戶名:postgres,密碼:123456),實現(xiàn)核心操作,用法與PyMySQL類似,重點突出差異點。

import psycopg2
from psycopg2 import Error
def postgresql_demo():
    # 1. 數(shù)據(jù)庫連接參數(shù)
    db_config = {
        "host": "localhost",
        "port": 5432,          # PostgreSQL默認端口5432(區(qū)別于MySQL的3306)
        "user": "postgres",    # PostgreSQL默認用戶名postgres
        "password": "123456",
        "database": "test_pg"
    }
    connection = None
    cursor = None
    try:
        # 2. 建立連接
        connection = psycopg2.connect(**db_config)
        cursor = connection.cursor()
        print("? 成功連接到PostgreSQL數(shù)據(jù)庫")
        # 3. 建表(支持JSON類型,PostgreSQL特色)
        create_table_sql = """
        CREATE TABLE IF NOT EXISTS student_info (
            id SERIAL PRIMARY KEY,  # PostgreSQL自增用SERIAL
            name VARCHAR(50) NOT NULL,
            age INT,
            info JSONB  # 支持JSONB類型(高效存儲JSON數(shù)據(jù))
        );
        """
        cursor.execute(create_table_sql)
        print("? 表創(chuàng)建成功(若不存在)")
        # 4. 插入數(shù)據(jù)(支持JSON類型數(shù)據(jù))
        insert_sql = "INSERT INTO student_info (name, age, info) VALUES (%s, %s, %s)"
        # PostgreSQL占位符同樣是%s,與PyMySQL一致
        insert_data = ("張三", 20, '{"class": "一班", "score": 90}')  # JSON數(shù)據(jù)傳字符串
        cursor.execute(insert_sql, insert_data)
        # 批量插入
        batch_data = [
            ("李四", 21, '{"class": "二班", "score": 85}'),
            ("王五", 19, '{"class": "一班", "score": 95}')
        ]
        cursor.executemany(insert_sql, batch_data)
        connection.commit()
        print(f"? 插入數(shù)據(jù)成功,影響行數(shù):{cursor.rowcount}")
        # 5. 查詢數(shù)據(jù)(支持JSON字段查詢,PostgreSQL特色)
        select_sql = "SELECT * FROM student_info WHERE info->>'class' = %s"
        cursor.execute(select_sql, ("一班",))  # 查詢class為一班的學生
        result = cursor.fetchall()
        print(f"? 一班學生(共{len(result)}條):")
        for row in result:
            print(f"id: {row[0]}, 姓名: {row[1]}, 年齡: {row[2]}, 信息: {row[3]}")
        # 6. 更新、刪除操作(與PyMySQL一致)
        update_sql = "UPDATE student_info SET age = %s WHERE name = %s"
        cursor.execute(update_sql, (22, "張三"))
        connection.commit()
        delete_sql = "DELETE FROM student_info WHERE name = %s"
        cursor.execute(delete_sql, ("李四",))
        connection.commit()
    except Error as e:
        print(f"? 數(shù)據(jù)庫操作異常:{e}")
        if connection:
            connection.rollback()
    finally:
        # 關閉資源
        if cursor:
            cursor.close()
        if connection:
            connection.close()
            print("? 數(shù)據(jù)庫連接已關閉")
if __name__ == "__main__":
    postgresql_demo()

(4)關鍵注意事項

  • 端口差異:PostgreSQL默認端口是 5432,區(qū)別于MySQL的3306,避免端口混淆;
  • 自增字段:PostgreSQL自增字段用 SERIALBIGSERIAL(大整數(shù)),而非MySQL的AUTO_INCREMENT;
  • JSON支持:PostgreSQL原生支持JSON/JSONB類型,插入JSON數(shù)據(jù)時需傳入字符串格式,查詢時可通過 ->(獲取JSON對象)、->>(獲取JSON字符串)操作JSON字段;
  • 默認用戶:PostgreSQL默認用戶是 postgres,默認無密碼(需手動設置密碼);
  • 安裝問題:若安裝psycopg2失敗,優(yōu)先安裝psycopg2-binary(二進制版本),避免編譯依賴問題。

三、非關系型數(shù)據(jù)庫操作庫(重點)

非關系型數(shù)據(jù)庫(NoSQL)無需固定表結構,支持靈活的數(shù)據(jù)存儲(如JSON、鍵值對),適合大數(shù)據(jù)量、高并發(fā)、數(shù)據(jù)結構不固定的場景。以下講解Python中最常用的兩個NoSQL數(shù)據(jù)庫操作庫:MongoDB(文檔型)和Redis(鍵值對型)。

1. pymongo(適配MongoDB數(shù)據(jù)庫)

MongoDB是一款主流的文檔型NoSQL數(shù)據(jù)庫,數(shù)據(jù)以JSON格式(BSON)存儲,無需固定表結構,靈活易用,適合Web開發(fā)、日志存儲、數(shù)據(jù)分析等場景。Python中操作MongoDB的主流庫是 pymongo(MongoDB官方推薦)。

(1)庫介紹

  • 定位:MongoDB官方Python客戶端庫,功能完整、易用,支持MongoDB所有核心特性;
  • 核心功能:支持文檔的增刪改查、索引、聚合查詢、事務、批量操作等,適配MongoDB 3.6+版本;
  • 優(yōu)勢:API簡潔、靈活,與MongoDB原生語法高度一致,支持連接池、異步操作(motor庫);
  • 劣勢:復雜聚合查詢的語法稍繁瑣,需熟悉MongoDB原生聚合管道。

(2)安裝步驟

# 安裝pymongo
pip install pymongo
# 若需支持異步操作(如FastAPI項目),安裝motor(pymongo的異步版本)
# pip install motor

(3)核心用法與實戰(zhàn)示例

MongoDB核心概念(與關系型數(shù)據(jù)庫對應):數(shù)據(jù)庫(Database)→ 集合(Collection,對應表)→ 文檔(Document,對應行),無需提前建庫、建集合(插入文檔時自動創(chuàng)建)。

示例場景:連接本地MongoDB數(shù)據(jù)庫(默認端口27017,無用戶名密碼),實現(xiàn)「插入文檔→查詢文檔→更新文檔→刪除文檔」完整操作。

from pymongo import MongoClient
from pymongo.errors import PyMongoError
def mongodb_demo():
    # 1. 數(shù)據(jù)庫連接參數(shù)
    mongo_url = "mongodb://localhost:27017/"  # MongoDB默認地址+端口
    db_name = "test_mongo"  # 數(shù)據(jù)庫名(不存在則自動創(chuàng)建)
    collection_name = "user"  # 集合名(對應關系型數(shù)據(jù)庫的表,不存在則自動創(chuàng)建)
    client = None
    try:
        # 2. 建立連接(創(chuàng)建MongoClient對象)
        client = MongoClient(mongo_url)
        print("? 成功連接到MongoDB數(shù)據(jù)庫")
        # 3. 獲取數(shù)據(jù)庫對象
        db = client[db_name]
        # 4. 獲取集合對象(對應表)
        collection = db[collection_name]
        # 5. 執(zhí)行操作(插入→查詢→更新→刪除)
        # 5.1 插入文檔(單條+批量)
        # 單條插入(文檔是字典格式,對應JSON)
        single_doc = {
            "name": "張三",
            "age": 25,
            "gender": "男",
            "info": {"city": "北京", "job": "程序員"}
        }
        insert_result = collection.insert_one(single_doc)
        print(f"? 單條插入成功,文檔ID:{insert_result.inserted_id}")
        # 批量插入(傳入列表,每個元素是字典)
        batch_docs = [
            {"name": "李四", "age": 28, "gender": "男", "info": {"city": "上海", "job": "產品經理"}},
            {"name": "王五", "age": 23, "gender": "女", "info": {"city": "廣州", "job": "設計師"}},
            {"name": "趙六", "age": 30, "gender": "男", "info": {"city": "深圳", "job": "測試工程師"}}
        ]
        batch_result = collection.insert_many(batch_docs)
        print(f"? 批量插入成功,文檔IDs:{batch_result.inserted_ids}")
        # 5.2 查詢文檔(單條+多條+條件查詢)
        # 單條查詢(根據(jù)條件查詢,find_one返回第一個匹配文檔)
        single_query = collection.find_one({"name": "張三"})
        print(f"? 單條查詢結果:{single_query}")
        # 多條查詢(查詢所有gender為男的文檔,返回游標,需遍歷)
        multi_query = collection.find({"gender": "男"})
        print("? 所有男性用戶:")
        for doc in multi_query:
            print(doc)
        # 條件查詢(查詢age>25的文檔,只返回name和age字段,隱藏_id)
        condition_query = collection.find(
            {"age": {"$gt": 25}},  # 條件:age>25(MongoDB條件語法)
            {"name": 1, "age": 1, "_id": 0}  # 1:顯示,0:隱藏
        )
        print("? 年齡>25的用戶(僅顯示姓名和年齡):")
        for doc in condition_query:
            print(doc)
        # 5.3 更新文檔(單條+多條)
        # 單條更新(更新name為張三的文檔,將age改為26)
        update_single = collection.update_one(
            {"name": "張三"},  # 查詢條件
            {"$set": {"age": 26, "info.city": "杭州"}}  # 更新操作:$set表示修改指定字段
        )
        print(f"? 單條更新成功,匹配行數(shù):{update_single.matched_count},修改行數(shù):{update_single.modified_count}")
        # 多條更新(更新所有gender為男的文檔,將age加1)
        update_multi = collection.update_many(
            {"gender": "男"},
            {"$inc": {"age": 1}}  # $inc表示自增
        )
        print(f"? 多條更新成功,匹配行數(shù):{update_multi.matched_count},修改行數(shù):{update_multi.modified_count}")
        # 5.4 刪除文檔(單條+多條)
        # 單條刪除(刪除name為趙六的文檔)
        delete_single = collection.delete_one({"name": "趙六"})
        print(f"? 單條刪除成功,刪除行數(shù):{delete_single.deleted_count}")
        # 多條刪除(刪除age>30的文檔)
        delete_multi = collection.delete_many({"age": {"$gt": 30}})
        print(f"? 多條刪除成功,刪除行數(shù):{delete_multi.deleted_count}")
    except PyMongoError as e:
        print(f"? MongoDB操作異常:{e}")
    finally:
        # 關閉連接
        if client:
            client.close()
            print("? MongoDB連接已關閉")
if __name__ == "__main__":
    mongodb_demo()

(4)關鍵注意事項

  • 連接方式:MongoDB默認無用戶名密碼,若開啟權限認證,連接URL格式為 mongodb://username:password@host:port/;
  • 文檔格式:插入的文檔必須是字典格式(對應BSON),支持嵌套字典(如示例中的info字段);
  • 查詢條件:MongoDB的查詢條件使用特殊運算符(如 $gt:大于、$lt:小于、$in:包含),需熟悉其語法;
  • 更新操作:必須使用 $set、$inc 等更新運算符,否則會覆蓋整個文檔(如直接傳入{“age”:26},會刪除其他所有字段);
  • 游標特性:find()方法返回的是游標,而非直接返回數(shù)據(jù),需遍歷游標獲取所有結果(可使用list()轉換為列表,但大數(shù)據(jù)量不推薦);
  • 索引優(yōu)化:大數(shù)據(jù)量查詢時,需給常用查詢字段建立索引(如collection.create_index(“name”)),提升查詢效率。

2. redis-py(適配Redis數(shù)據(jù)庫)

Redis是一款高性能的鍵值對型NoSQL數(shù)據(jù)庫,數(shù)據(jù)存儲在內存中,支持多種數(shù)據(jù)結構(字符串、列表、哈希、集合、有序集合),適合緩存、會話存儲、計數(shù)器、消息隊列等場景。Python中操作Redis的主流庫是redis-py(Redis官方推薦)。

(1)庫介紹

  • 定位:Redis官方Python客戶端庫,輕量、高效,支持Redis所有核心特性和數(shù)據(jù)結構;
  • 核心功能:支持字符串、列表、哈希等所有Redis數(shù)據(jù)結構的操作,支持事務、管道、發(fā)布訂閱、連接池等;
  • 優(yōu)勢:執(zhí)行效率高(貼合Redis原生性能),API簡潔,支持連接池,適配Redis 2.6+版本;
  • 劣勢:不支持異步操作(需使用aioredis庫,異步版本),復雜場景需手動封裝。

(2)安裝步驟

# 安裝redis-py(推薦最新版本)
pip install redis
# 若需異步操作(如異步Web項目),安裝aioredis
# pip install aioredis

(3)核心用法與實戰(zhàn)示例

Redis核心是「鍵值對」,支持多種數(shù)據(jù)結構,每種數(shù)據(jù)結構有對應的操作方法。示例場景:連接本地Redis數(shù)據(jù)庫(默認端口6379,無用戶名密碼),演示常用數(shù)據(jù)結構的核心操作。

import redis
from redis.exceptions import RedisError
def redis_demo():
    # 1. 數(shù)據(jù)庫連接參數(shù)
    redis_config = {
        "host": "localhost",
        "port": 6379,          # Redis默認端口6379
        "password": "",        # 若有密碼,傳入密碼字符串
        "db": 0,               # 選擇數(shù)據(jù)庫(Redis默認有16個數(shù)據(jù)庫,編號0-15)
        "decode_responses": True  # 關鍵:設置為True,返回字符串(默認返回bytes類型)
    }
    r = None
    try:
        # 2. 建立連接(創(chuàng)建Redis對象,推薦使用連接池)
        # 方式1:直接創(chuàng)建連接(簡單場景)
        r = redis.Redis(**redis_config)
        # 方式2:使用連接池(生產環(huán)境推薦,避免頻繁創(chuàng)建/關閉連接)
        # pool = redis.ConnectionPool(**redis_config)
        # r = redis.Redis(connection_pool=pool)
        # 驗證連接(ping()返回True表示連接成功)
        if r.ping():
            print("? 成功連接到Redis數(shù)據(jù)庫")
        # 3. 執(zhí)行操作(常用數(shù)據(jù)結構:字符串、哈希、列表、集合)
        # 3.1 字符串類型(String):最基礎的鍵值對,適合緩存、計數(shù)器
        # 設置值(key=name, value=張三,過期時間60秒)
        r.set("name", "張三", ex=60)
        # 獲取值
        name = r.get("name")
        print(f"? 字符串查詢:name = {name}")
        # 自增(計數(shù)器)
        r.incr("count")  # count從0變?yōu)?
        r.incr("count", 2)  # count從1變?yōu)?
        count = r.get("count")
        print(f"? 計數(shù)器:count = {count}")
        # 刪除值
        r.delete("count")
        print(f"? 字符串刪除:count是否存在 = {r.exists('count')}")  # exists返回0表示不存在
        # 3.2 哈希類型(Hash):適合存儲對象(如用戶信息),鍵值對嵌套
        # 設置哈希值(key=user:1,字段name、age、gender)
        r.hset("user:1", mapping={
            "name": "李四",
            "age": 28,
            "gender": "男"
        })
        # 獲取單個字段值
        user_name = r.hget("user:1", "name")
        print(f"? 哈希查詢(單個字段):user:1.name = {user_name}")
        # 獲取所有字段和值
        user_all = r.hgetall("user:1")
        print(f"? 哈希查詢(所有字段):user:1 = {user_all}")
        # 獲取所有字段名
        user_fields = r.hkeys("user:1")
        print(f"? 哈希查詢(所有字段名):user:1.fields = {user_fields}")
        # 3.3 列表類型(List):有序、可重復,適合消息隊列、排行榜
        # 向列表左側添加值
        r.lpush("book_list", "Python編程", "Java編程", "SQL必知必會")
        # 向列表右側添加值
        r.rpush("book_list", "Redis實戰(zhàn)")
        # 獲取列表長度
        book_len = r.llen("book_list")
        print(f"? 列表長度:book_list.length = {book_len}")
        # 獲取列表所有值(0表示第一個,-1表示最后一個)
        book_all = r.lrange("book_list", 0, -1)
        print(f"? 列表查詢(所有值):book_list = {book_all}")
        # 彈出列表左側值(消息隊列常用)
        book_pop = r.lpop("book_list")
        print(f"? 列表彈出(左側):彈出值 = {book_pop},剩余列表 = {r.lrange('book_list', 0, -1)}")
        # 3.4 集合類型(Set):無序、不可重復,適合去重、交集/并集查詢
        # 向集合添加值
        r.sadd("user_set", "張三", "李四", "王五", "張三")  # 重復值會自動去重
        # 獲取集合所有值
        user_set_all = r.smembers("user_set")
        print(f"? 集合查詢(所有值):user_set = {user_set_all}")
        # 判斷值是否在集合中
        is_exist = r.sismember("user_set", "張三")
        print(f"? 集合判斷:張三是否在user_set中 = {is_exist}")
        # 獲取集合長度
        user_set_len = r.scard("user_set")
        print(f"? 集合長度:user_set.length = {user_set_len}")
        # 3.5 事務操作(Redis事務:批量執(zhí)行,要么全部成功,要么全部失?。?
        pipe = r.pipeline()  # 創(chuàng)建管道(事務載體)
        pipe.set("tx1", "test1")
        pipe.set("tx2", "test2")
        pipe.incr("tx3")
        pipe.execute()  # 執(zhí)行事務
        print(f"? 事務執(zhí)行成功:tx1 = {r.get('tx1')}, tx2 = {r.get('tx2')}, tx3 = {r.get('tx3')}")
    except RedisError as e:
        print(f"? Redis操作異常:{e}")
    finally:
        # 關閉連接(使用連接池時,無需手動關閉,連接池會自動管理)
        if r:
            r.close()
            print("? Redis連接已關閉")
if __name__ == "__main__":
    redis_demo()

(4)關鍵注意事項

  • decode_responses參數(shù):必須設置為 True,否則所有返回值都是bytes類型(需手動解碼為字符串),開發(fā)中極易出錯;
  • 連接池優(yōu)化:生產環(huán)境必須使用連接池(ConnectionPool),避免頻繁創(chuàng)建/關閉連接,提升效率;連接池參數(shù)可根據(jù)并發(fā)量調整(如max_connections=100);
  • 數(shù)據(jù)結構選型:根據(jù)場景選擇合適的數(shù)據(jù)結構(如緩存用戶信息用Hash,消息隊列用List,計數(shù)器用String,去重用Set);
  • 過期時間:緩存場景需給鍵設置過期時間(ex參數(shù),單位秒;px參數(shù),單位毫秒),避免內存溢出;
  • 事務特性:Redis事務是“弱事務”,僅保證批量執(zhí)行,不支持回滾(執(zhí)行過程中出錯,已執(zhí)行的命令不會回滾);
  • 密碼與權限:生產環(huán)境需給Redis設置密碼,連接時傳入password參數(shù);同時限制Redis訪問IP,避免安全漏洞;
  • 序列化:若需存儲字典、列表等復雜數(shù)據(jù),需先序列化(如json.dumps()),讀取時再反序列化(json.loads()),因為Redis僅支持字符串類型的鍵值對。

四、通用進階技巧(生產環(huán)境必備)

無論使用哪種數(shù)據(jù)庫、哪種操作庫,以下進階技巧都是生產環(huán)境必備,可提升腳本穩(wěn)定性、效率和安全性,統(tǒng)一梳理如下:

1. 異常處理全覆蓋

必須捕獲所有可能的異常(如連接失敗、SQL錯誤、Redis超時等),避免程序崩潰;同時在異常時做兜底處理(如事務回滾、日志記錄),便于問題排查。

2. 連接池管理

生產環(huán)境中,頻繁創(chuàng)建/關閉數(shù)據(jù)庫連接會嚴重影響效率,所有庫都支持連接池(PyMySQL用DBUtils,pymongo用MongoClient內置連接池,redis用ConnectionPool),需合理配置連接池參數(shù)(最大連接數(shù)、超時時間等)。

3. 避免SQL注入(關系型數(shù)據(jù)庫)

所有關系型數(shù)據(jù)庫(MySQL、PostgreSQL、SQLite)的SQL語句,必須使用占位符傳遞參數(shù),不可直接拼接SQL字符串,避免SQL注入漏洞(重點?。?。

4. 日志記錄

在數(shù)據(jù)庫操作的關鍵節(jié)點(連接、執(zhí)行SQL、異常)添加日志記錄(使用Python內置logging庫),便于后續(xù)排查問題(如定位SQL執(zhí)行失敗的原因、連接超時的場景)。

5. 數(shù)據(jù)序列化(非關系型數(shù)據(jù)庫)

MongoDB、Redis存儲復雜數(shù)據(jù)(字典、列表)時,需先序列化(如json.dumps()),讀取時反序列化,確保數(shù)據(jù)完整性。

6. 批量操作優(yōu)先

插入、更新、刪除大量數(shù)據(jù)時,優(yōu)先使用批量操作(如executemany、insert_many、hmset),避免單條循環(huán)操作,提升執(zhí)行效率(批量操作可減少網(wǎng)絡交互次數(shù))。

7. 權限與安全

生產環(huán)境中,數(shù)據(jù)庫必須設置密碼、限制訪問IP;敏感數(shù)據(jù)(如密碼、數(shù)據(jù)庫地址)不可硬編碼在代碼中,需使用配置文件(如config.ini)或環(huán)境變量存儲。

五、總結

Python中數(shù)據(jù)庫操作庫豐富多樣,核心可分為「關系型數(shù)據(jù)庫庫」和「非關系型數(shù)據(jù)庫庫」,選擇時需遵循「場景適配」原則,總結如下:

1. 庫選型建議

  • MySQL數(shù)據(jù)庫:優(yōu)先使用 PyMySQL(Python 3.x,跨平臺);
  • SQLite數(shù)據(jù)庫:直接使用Python內置 sqlite3(輕量、無需部署,適合小型場景);
  • PostgreSQL數(shù)據(jù)庫:優(yōu)先使用 psycopg2-binary(二進制版本,安裝簡單,效率高);
  • MongoDB數(shù)據(jù)庫:優(yōu)先使用 pymongo(官方推薦,功能完整),異步場景用motor;
  • Redis數(shù)據(jù)庫:優(yōu)先使用 redis-py(官方推薦,高效),異步場景用aioredis。

2. 核心要點

  • 所有數(shù)據(jù)庫操作,均遵循「連接→操作→關閉」的核心邏輯,重點關注資源釋放;
  • 生產環(huán)境必備:異常處理、連接池、日志記錄、權限安全,缺一不可;
  • 避免常見坑點:SQL注入(關系型)、bytes類型(Redis)、文檔覆蓋(MongoDB)、連接泄露(所有庫);
  • 實戰(zhàn)為王:本文所有示例均可直接復制運行,建議結合實際數(shù)據(jù)庫環(huán)境,動手實操一遍,快速掌握核心用法。

Python數(shù)據(jù)庫操作庫的核心是「簡化與數(shù)據(jù)庫的交互」,無需深入理解數(shù)據(jù)庫底層原理,只需掌握對應庫的API和選型原則,就能高效完成數(shù)據(jù)庫操作。后續(xù)可根據(jù)具體項目場景,深入學習某一個庫的高級特性(如MongoDB聚合查詢、Redis管道、PostgreSQL JSON操作),進一步提升開發(fā)效率。

到此這篇關于Python中數(shù)據(jù)庫操作庫詳解的文章就介紹到這了,更多相關Python數(shù)據(jù)庫操作庫內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • python開發(fā)入門——set的使用

    python開發(fā)入門——set的使用

    這篇文章主要介紹了python set的使用,幫助大家更好的理解和學習python,感興趣的朋友可以了解下
    2020-09-09
  • python垃圾回收機制(GC)原理解析

    python垃圾回收機制(GC)原理解析

    這篇文章主要介紹了python垃圾回收機制(GC)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • 使用Python代碼實現(xiàn)PDF文檔與SVG文件之間的轉換

    使用Python代碼實現(xiàn)PDF文檔與SVG文件之間的轉換

    PDF作為普遍采用的文件格式,確保了文檔的一致性和可靠性,而SVG(可縮放矢量圖形)則因其矢量性質,在網(wǎng)頁設計、高分辨率打印及動態(tài)交互內容中展現(xiàn)出無與倫比的優(yōu)勢,本文將介紹如何使用Python將PDF文件轉換為SVG文件以及將SVG文件轉換為PDF文件,需要的朋友可以參考下
    2024-05-05
  • Python中staticmethod和classmethod的作用與區(qū)別

    Python中staticmethod和classmethod的作用與區(qū)別

    今天小編就為大家分享一篇關于Python中staticmethod和classmethod的作用與區(qū)別,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Numpy中np.random.rand()和np.random.randn() 用法和區(qū)別詳解

    Numpy中np.random.rand()和np.random.randn() 用法和區(qū)別詳解

    這篇文章主要介紹了Numpy中np.random.rand()和np.random.randn() 用法和區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • 7個實用的Python自動化代碼別再重復造輪子了

    7個實用的Python自動化代碼別再重復造輪子了

    關于Python有一句名言:不要重復造輪子,給大家分享經過Python3.6.4調試通過的代碼,感興趣的朋友跟隨小編一起看看吧
    2023-11-11
  • Python函數(shù)中的可變長參數(shù)詳解

    Python函數(shù)中的可變長參數(shù)詳解

    在本篇文章里小編給大家整理的是關于Python函數(shù)中的可變長參數(shù)的相關知識點內容,有需要的朋友們參考下。
    2019-09-09
  • 備戰(zhàn)618!用Python腳本幫你實現(xiàn)淘寶秒殺

    備戰(zhàn)618!用Python腳本幫你實現(xiàn)淘寶秒殺

    本次的文章,分享一個淘寶秒殺腳本,這個腳本用Python編寫,使用了Python庫selenium,并且通過selenium + chromedriver,用程序控制chrome瀏覽器,完成搶購的一系列操作.有了這個腳本,大家至少可以與其他的機器人站在同一起跑線上,公平搶購喜歡的寶貝 ,需要的朋友可以參考下
    2021-06-06
  • tensorflow的計算圖總結

    tensorflow的計算圖總結

    這篇文章主要介紹了tensorflow的計算圖總結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • 使用Python生成條形碼圖片的實戰(zhàn)代碼

    使用Python生成條形碼圖片的實戰(zhàn)代碼

    在自動化生產、物流配送、商超系統(tǒng)等日常業(yè)務中,條形碼已成為數(shù)據(jù)快速讀取與追蹤的核心方式,相比手工設計,使用 Python 編程生成條形碼圖片,能顯著提升效率并支持批量處理,本文將介紹如何使用Python生成條形碼,需要的朋友可以參考下
    2025-05-05

最新評論

普陀区| 信宜市| 镇雄县| 鄂托克旗| 泰安市| 雷州市| 什邡市| 宜章县| 西平县| 德化县| 青岛市| 泰和县| 介休市| 舟曲县| 牟定县| 合川市| 台州市| 中超| 大足县| 青冈县| 赞皇县| 德钦县| 嘉祥县| 沁水县| 青神县| 宣化县| 云安县| 吉林市| 宾阳县| 滦平县| 平原县| 阿合奇县| 潮州市| 育儿| 嘉善县| 江安县| 饶阳县| 莲花县| 江口县| 维西| 霍山县|