0

0

如何使用Python连接PostgreSQL?psycopg2

絕刀狂花

絕刀狂花

发布时间:2025-07-09 12:09:01

|

268人浏览过

|

来源于php中文网

原创

要使用python连接postgresql数据库,最常用且稳健的方式是使用psycopg2库。1. 首先安装psycopg2或更便捷的psycopg2-binary;2. 使用psycopg2.connect()方法建立连接,传入host、database、user、password和port等参数;3. 创建游标对象执行sql语句;4. 操作完成后提交事务并关闭连接。为保障安全,应避免将数据库连接参数硬编码在代码中,推荐使用环境变量、.env配置文件(配合python-dotenv)或配置管理服务(如vault、aws secrets manager)。错误处理方面,需通过try...except...finally结构捕获psycopg2.error及其子类异常,并在出错时回滚事务。事务管理上,必须显式调用connection.commit()提交更改或connection.rollback()撤销操作。高级用法包括:使用参数化查询防止sql注入;选择dictcursor或namedtuplecursor提升结果可读性;使用连接池(如psycopg2.pool)优化高并发性能;异步场景下考虑asyncpg替代psycopg2。这些实践能显著增强代码安全性、稳定性和性能。

如何使用Python连接PostgreSQL?psycopg2

连接Python与PostgreSQL数据库,最常用也最稳健的选择就是psycopg2库。它提供了一个非常直接且符合DB-API 2.0规范的接口,让你能够像操作本地对象一样操作数据库。核心在于先安装psycopg2,然后通过psycopg2.connect()建立连接,接着创建游标执行SQL语句,最后别忘了提交事务并关闭连接。这套流程一旦掌握,数据库操作就变得清晰可控。

如何使用Python连接PostgreSQL?psycopg2

解决方案

要使用psycopg2连接PostgreSQL,你首先需要安装它。我个人偏好安装psycopg2-binary,因为它省去了编译C语言扩展的麻烦,对于大多数用户来说,这简直是福音。

pip install psycopg2-binary

接下来,就是编写Python代码。一个典型的连接、查询和关闭的流程会是这样:

立即学习Python免费学习笔记(深入)”;

如何使用Python连接PostgreSQL?psycopg2
import psycopg2
from psycopg2 import Error

# 数据库连接参数
# 在实际项目中,这些参数绝不应该硬编码,后面我会聊聊如何安全管理
DB_HOST = "localhost"
DB_NAME = "your_database_name"
DB_USER = "your_username"
DB_PASSWORD = "your_password"
DB_PORT = "5432" # PostgreSQL默认端口

connection = None # 初始化连接变量
cursor = None     # 初始化游标变量

try:
    # 建立数据库连接
    connection = psycopg2.connect(
        host=DB_HOST,
        database=DB_NAME,
        user=DB_USER,
        password=DB_PASSWORD,
        port=DB_PORT
    )

    # 创建一个游标对象,用于执行SQL命令
    # 默认游标返回的是元组,如果需要字典形式的结果,可以使用 psycopg2.extras.DictCursor
    cursor = connection.cursor()

    # 示例1:创建一个表(如果不存在)
    create_table_query = """
    CREATE TABLE IF NOT EXISTS users (
        id SERIAL PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        email VARCHAR(100) UNIQUE
    );
    """
    cursor.execute(create_table_query)
    connection.commit() # 提交事务,使更改生效
    print("表 'users' 已创建或已存在。")

    # 示例2:插入数据
    # 注意:这里使用参数化查询(%s),这是防止SQL注入的关键!
    insert_query = "INSERT INTO users (name, email) VALUES (%s, %s);"
    user_data = ("张三", "zhangsan@example.com")
    cursor.execute(insert_query, user_data)
    connection.commit()
    print("数据插入成功。")

    # 示例3:查询数据
    select_query = "SELECT id, name, email FROM users WHERE name = %s;"
    cursor.execute(select_query, ("张三",))

    # 获取所有查询结果
    records = cursor.fetchall()
    print("\n查询结果:")
    for row in records:
        print(f"ID: {row[0]}, 姓名: {row[1]}, 邮箱: {row[2]}")

except (Exception, Error) as error:
    print(f"连接或操作数据库时发生错误: {error}")
    if connection:
        connection.rollback() # 发生错误时回滚事务

finally:
    # 无论成功或失败,都确保关闭游标和连接
    if cursor:
        cursor.close()
    if connection:
        connection.close()
    print("PostgreSQL连接已关闭。")

PostgreSQL连接参数如何安全配置与管理?

说实话,把数据库的账号密码直接写在代码里,那简直是给自己挖坑。在实际开发中,尤其是在团队协作和部署到生产环境时,连接参数的安全管理是头等大事。我通常会考虑几种方案,它们各有优劣。

最常见的参数包括:host(数据库服务器地址,如localhost或IP)、database(要连接的数据库名)、user(用户名)、password(密码)以及port(端口,PostgreSQL默认是5432)。

如何使用Python连接PostgreSQL?psycopg2

至于安全配置,我强烈推荐以下几种方式,优先级从高到低:

  1. 环境变量 (Environment Variables): 这是最推荐的方式。将数据库凭证设置为操作系统的环境变量,你的代码运行时直接读取这些变量。例如:export DB_USER=myuser。代码中通过os.environ.get('DB_USER')来获取。这样做的好处是代码库里完全不包含敏感信息,且在不同环境(开发、测试、生产)部署时,只需修改环境变量即可,无需改动代码。我个人觉得,虽然初始设置有点麻烦,但长期来看,它最干净。

  2. 配置文件 (.env files with python-dotenv): 对于本地开发环境,或者不方便设置系统环境变量的场景,使用.env文件配合python-dotenv库是个不错的折衷方案。你创建一个.env文件(记得把它添加到.gitignore里,绝不能提交到版本控制!),里面写上DB_USER=myuser,然后Python代码里用dotenv_values()load_dotenv()来加载。

    # .env 文件示例
    DB_HOST=localhost
    DB_NAME=mydb
    DB_USER=myuser
    DB_PASSWORD=mypassword
    DB_PORT=5432
    # Python代码
    from dotenv import load_dotenv
    import os
    
    load_dotenv() # 加载 .env 文件中的环境变量
    
    DB_HOST = os.getenv("DB_HOST")
    DB_NAME = os.getenv("DB_NAME")
    # ... 其他参数

    这种方式兼顾了便捷性和安全性,很适合项目初期。

  3. 配置管理服务 (如Vault, AWS Secrets Manager): 对于大型企业级应用,或者需要更高级别安全策略的场景,会引入专门的秘密管理服务。这些服务能够动态生成、轮换凭证,并提供细粒度的访问控制。虽然集成起来更复杂,但安全性达到了最高级别。这通常是架构师和运维团队会考虑的。

无论哪种方式,核心原则都是:敏感信息绝不能硬编码在代码中,更不能提交到版本控制系统。 我见过太多因为不小心把凭证推到GitHub而引发的安全事故,那种感觉就像是把家门钥匙直接挂在了大街上。

数据库操作中如何处理常见错误和事务?

在和数据库打交道时,错误和事务管理是两个绕不开的话题。我个人觉得,一个健壮的数据库交互代码,必须把这两点考虑进去,否则迟早会遇到数据不一致或者程序崩溃的问题。

AIPAI
AIPAI

AI视频创作智能体

下载

错误处理

psycopg2在执行SQL操作时,如果遇到问题,会抛出psycopg2.Error或其子类的异常。最常见的错误类型包括:

  • psycopg2.IntegrityError: 当你尝试插入重复的主键、违反唯一约束或外键约束时。比如,你试图插入一个邮箱地址已经存在的用户。
  • psycopg2.ProgrammingError: SQL语法错误、表或列不存在等。
  • psycopg2.OperationalError: 连接问题,如数据库服务器宕机、网络不通等。

我的经验是,使用try...except...finally结构是处理数据库错误的黄金法则。

try:
    # 数据库操作,比如插入一条可能违反唯一约束的数据
    cursor.execute("INSERT INTO users (name, email) VALUES (%s, %s);", ("李四", "zhangsan@example.com"))
    connection.commit()
except psycopg2.IntegrityError as e:
    print(f"数据完整性错误:{e}")
    if connection:
        connection.rollback() # 发生完整性错误时,回滚当前事务
except psycopg2.ProgrammingError as e:
    print(f"SQL编程错误:{e}")
    if connection:
        connection.rollback()
except psycopg2.Error as e: # 捕获所有psycopg2相关的错误
    print(f"数据库操作通用错误:{e}")
    if connection:
        connection.rollback()
except Exception as e: # 捕获其他任何Python异常
    print(f"未知错误:{e}")
    if connection:
        connection.rollback()
finally:
    # 确保资源被释放
    if cursor:
        cursor.close()
    if connection:
        connection.close()

关键在于,一旦发生错误,特别是影响数据状态的错误(如插入、更新、删除),你几乎总是需要调用connection.rollback()。这能撤销当前事务中所有未提交的更改,保证数据库回到操作前的状态,避免数据不一致。

事务管理

事务(Transaction)是数据库操作中一个非常重要的概念,它确保了一组操作要么全部成功,要么全部失败,从而维护数据的完整性和一致性。PostgreSQL默认是自动提交模式,但psycopg2默认是手动提交,这意味着你需要显式地调用connection.commit()来保存更改。

  • connection.commit(): 当你执行了INSERTUPDATEDELETECREATE TABLE等修改数据库状态的SQL语句后,必须调用commit()才能将这些更改永久保存到数据库中。如果没有调用,即使代码执行成功,这些更改也只存在于当前会话的内存中,一旦连接关闭,所有更改都会丢失。我刚开始用的时候就犯过这个错,查了半天数据没进去,结果发现是忘了commit
  • connection.rollback(): 当一组操作中的任何一个失败,或者你决定放弃当前事务中的所有更改时,调用rollback()可以撤销所有自上次commit()以来或自连接建立以来的所有操作。这对于错误恢复至关重要。

一个典型的事务流程:

  1. 开始事务(psycopg2连接后默认就处于一个事务中)。
  2. 执行一系列SQL操作(比如先插入订单,再更新库存)。
  3. 如果所有操作都成功,调用connection.commit()
  4. 如果任何一个操作失败,或者捕获到异常,调用connection.rollback()
try:
    # 假设这是一个转账操作:从A扣钱,给B加钱
    cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE user_id = %s;", (1,))
    # 模拟一个错误,比如B用户不存在,或者网络断了
    # raise Exception("模拟网络错误")
    cursor.execute("UPDATE accounts SET balance = balance + 100 WHERE user_id = %s;", (2,))

    connection.commit() # 两步都成功,才提交
    print("转账成功!")
except Exception as e:
    print(f"转账失败:{e}")
    connection.rollback() # 任何一步失败,都回滚
    print("事务已回滚。")

理解并正确使用commit()rollback()是编写可靠数据库应用程序的基石。

除了基本的CRUD,psycopg2还有哪些高级用法或注意事项?

psycopg2不仅仅是提供CRUD(创建、读取、更新、删除)操作的基础,它还有一些高级特性和最佳实践,能够让你的代码更健壮、更高效。我个人在项目中会特别关注以下几点:

  1. SQL注入防护:参数化查询 (%s) 这是最重要的!永远不要直接将用户输入或任何动态值拼接到SQL字符串中。psycopg2提供了参数化查询机制,使用%s作为占位符,然后将参数作为execute()方法的第二个参数(一个元组或列表)传递。psycopg2会自动为你处理转义,有效防止SQL注入攻击。

    # 错误示范:存在SQL注入风险
    # user_input = "'; DROP TABLE users; --"
    # cursor.execute(f"SELECT * FROM users WHERE name = '{user_input}'")
    
    # 正确且安全的做法:使用参数化查询
    user_name = "Alice"
    cursor.execute("SELECT * FROM users WHERE name = %s;", (user_name,))

    这个习惯,必须养成。我见过太多因为忽视这一点而导致的安全漏洞,后果不堪设想。

  2. 游标类型:DictCursorNamedTupleCursor 默认的cursor对象在fetchall()fetchone()时返回的是元组。如果你想以字典形式访问结果(比如row['column_name']而不是row[0]),可以使用psycopg2.extras.DictCursor

    from psycopg2.extras import DictCursor
    
    # ... 连接代码 ...
    cursor = connection.cursor(cursor_factory=DictCursor)
    cursor.execute("SELECT id, name, email FROM users;")
    records = cursor.fetchall()
    for row in records:
        print(f"ID: {row['id']}, 姓名: {row['name']}, 邮箱: {row['email']}")

    对于更严格的类型检查和IDE自动补全,NamedTupleCursor也是一个不错的选择。选择哪种取决于你的项目习惯和需求,但它们都比纯元组更具可读性。

  3. 连接池 (psycopg2.pool) 频繁地建立和关闭数据库连接会带来性能开销。在Web应用或高并发场景下,使用连接池是标准做法。连接池预先创建并维护一定数量的数据库连接,当应用程序需要连接时,直接从池中获取一个可用的连接,用完后再归还到池中,而不是关闭。 psycopg2.pool模块提供了SimpleConnectionPoolThreadedConnectionPool等。

    from psycopg2.pool import SimpleConnectionPool
    
    # 创建连接池,最少1个连接,最多20个连接
    connection_pool = SimpleConnectionPool(1, 20,
                                           host=DB_HOST,
                                           database=DB_NAME,
                                           user=DB_USER,
                                           password=DB_PASSWORD,
                                           port=DB_PORT)
    
    conn = None
    try:
        conn = connection_pool.getconn() # 从池中获取一个连接
        cursor = conn.cursor()
        cursor.execute("SELECT version();")
        print(cursor.fetchone())
    except Exception as e:
        print(f"连接池操作错误: {e}")
    finally:
        if conn:
            connection_pool.putconn(conn) # 将连接归还到池中
        # 在程序结束时,记得关闭连接池
        # connection_pool.closeall()

    我个人觉得,对于任何稍微有点规模的应用,连接池都是必须的。它能显著提升性能和资源利用率。

  4. 异步操作 (AsyncPG) 虽然psycopg2本身是同步的,但如果你正在构建一个基于asyncio的异步Python应用,直接使用psycopg2会阻塞事件循环。在这种情况下,通常会选择asyncpg这个库,它是专门为异步PostgreSQL操作设计的,性能非常出色。虽然它不是psycopg2的一部分,但在讨论psycopg2的高级场景时,提到它非常有必要,因为它解决了psycopg2在异步环境下的痛点。

这些高级用法和注意事项,往往是在你从“能用”到“好用”甚至“生产可用”的路上,需要逐步掌握和实践的。一开始可能觉得复杂,但一旦用起来,你会发现它们能解决很多实际问题,让你的代码更健壮、更高效。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

401

2023.06.20

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

620

2023.07.25

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

354

2023.08.02

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

259

2023.08.09

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

606

2023.09.05

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

531

2023.09.20

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

647

2023.09.20

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

604

2023.09.22

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

8

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号