Psycopg2 教程
为 Python 初学者安装 Psycopg2
本文不打算全面介绍 psycopg2 的安装或 Python 包的管理,而是首先花点时间回顾基本的 Python 需求,以便遵循本教程,包括运行代码。
Python 可用于 主要的操作系统,例如 Windows、macOS 和 Linux 发行版。
许多操作系统上也预装了 Python,但在某些情况下默认的是 Python 2。
除非有特殊原因使用 Python 2(例如旧版安装程序),否则应避免使用 Python 2,而应使用 Python 3。但是,"Python 3" 版本的范围已变得很大,在次要版本之间存在差异。由于操作系统上的默认 Python 3 也各不相同,因此最佳实践是 *避免使用操作系统上的默认 Python 解释器*。
因此,请依赖独立于 OS 安装进行安装和配置的 Python 解释器。除了直接安装外,环境管理器或 IDE 提供的 Python 都是实现此目的的好方法。本文鼓励使用 Python 管理器,但并不特别推荐任何特定的管理器。
使用 Python 3 解释器,推荐的软件包安装方法是 pip。默认的 pip 安装将依赖于 Python 包索引 (PyPI) 来安装 psycogp2 库,以下为了方便起见提供了该库。
pip install psycopg2
本文的读者也应认识到 psycopg3 现已可用,并且本文专门针对 psycopg2 *仅此而已*。
使用 Python 访问 PostgreSQL
PostgreSQL 是一个流行的开源数据库,它为流行和不太常用的 编程语言 提供了应用程序编程接口。
Python 非常流行,用于许多目的,包括与 PostgreSQL 交互。
Python 有几个很棒的驱动程序,但 Psycopg2 是最受欢迎的驱动程序。最近发布了 Psycopg3,但 2 仍然在使用中占主导地位,本教程仅涵盖 Python 3 的 Psycopg2。
Psycopg2 是一个与 DB API 2.0 兼容的 PostgreSQL 驱动程序,正在积极开发中。它专为多线程应用程序而设计,并管理自己的连接池。
本文讨论了基础知识。
- 使用 Psycopg2 连接到 PostgreSQL
- 执行基本查询
- 事务范围
- 使用 Python 字典
本文假定 Python、Psycopg2、PostgreSQL 可用,并且用户 dbuser 能够创建数据库和表。根据需要替换您自己的连接参数。本文的测试平台是 Python 3.10.12、Psycopg2 2.9.3(依赖于 libpq 12.15)和 PostgreSQL 14.8。
以下代码片段利用了 Python 3 习语,但旨在简单且具有说明性。
导入 Psycopg2 并连接
#!/usr/bin/env python # # Small script to show PostgreSQL and Pyscopg together # import psycopg2 try: conn = psycopg2.connect("dbname='template1' user='dbuser' host='localhost' password='dbpass'") except: print("I am unable to connect to the database")
以上代码将导入驱动程序并尝试连接到数据库。如果连接失败,将向 STDOUT 打印一条语句。如果没有输出到您的 Python 解释器,则表示连接成功。
简单的查询和游标
下一步是定义一个游标来使用。重要的是要注意,Psycopg2 游标 与 PL/pgSQL 中使用的游标不同。
我们从与之前相同的简单连接方法开始。然后,我们使用 Python 上下文管理器 从 连接 中创建一个游标。游标具有 execute 方法,该方法可以将语句发送到数据库。当使用 with 上下文管理器方法时,事务处理的某些方面并不显式。例如,当语法 with 块完成时,游标将关闭。
#!/usr/bin/env python # # Small script to show Pyscopg2 cursor # import psycopg2 try: conn = psycopg2.connect("dbname='template1' user='dbuser' host='localhost' password='dbpass'") except: print("I am unable to connect to the database") # we use a context manager to scope the cursor session with conn.cursor() as curs: try: # simple single row system query curs.execute("SELECT version()") # returns a single row as a tuple single_row = curs.fetchone() # use an f-string to print the single tuple returned print(f"{single_row}") # simple multi row system query curs.execute("SELECT query, backend_type FROM pg_stat_activity") # a default install should include this query and some backend workers many_rows = curs.fetchmany(5) # use the * unpack operator to print many_rows which is a Python list print(*many_rows, sep = "\n") # a more robust way of handling errors except (Exception, psycopg2.DatabaseError) as error: print(error)
请依赖内联注释以获取一些逐行文档。
本节的另一部分是 fetch 方法示例。它们说明了从给定的执行的 SQL 语句中选择单个结果或参数驱动的多个结果。第一个 fetchone 返回一个 Python 元组,而 fetchmany(和 fetchall)返回一个元组列表,表示从数据库返回的行。两者都可以用于循环遍历结果,最适合应用程序。
事务
事务是一项重要的功能。应仔细考虑数据库 隔离 的配置,以获得一致性和性能的最佳平衡。本教程不会深入介绍此主题,但重点介绍了数据事务与影响数据库目录的操作之间的关键区别。
CREATE DATABASE 等操作不能在事务块中执行。请参阅 PostgreSQL 文档,并在使用 Python 上下文管理器时牢记这一点,上下文管理器处理会话事务 COMMIT 和 ROLLBACK。
为了完成数据目录操作,AUTOCOMMIT 设置允许相应地提交命令。
#!/usr/bin/env python # # Small script to show Pyscopg2 cursor # import psycopg2 conn = psycopg2.connect("dbname='template1' user='dbuser' host='localhost' password='dbpass'") print(f"Autocommit: {conn.autocommit} and Isolation Level: {conn.isolation_level}") # change the behavior of commit conn.autocommit = True print(f"Autocommit: {conn.autocommit} and Isolation Level: {conn.isolation_level}") with conn.cursor() as cur: try: cur.execute("CREATE DATABASE dbtest") except (Exception, psycopg2.DatabaseError) as error: print(error) conn.close() # to use the new database we create a new connection dbtest_conn = psycopg2.connect("dbname='dbtest' user='dbuser' host='localhost' password='dbpass'") with dbtest_conn: with dbtest_conn.cursor() as dbtest_curs: try: # create a table with a multi-line Python string surrounded by 3 double quotes dbtest_curs.execute(""" CREATE TABLE postgresqldotorg ( page_id SERIAL PRIMARY KEY, page_name VARCHAR(255) NOT NULL ) """) except (Exception, psycopg2.DatabaseError) as error: print(error) with dbtest_conn.cursor() as dbtest_curs: try: dbtest_curs.execute("INSERT INTO postgresqldotorg ( page_name ) VALUES ( 'psycopg2_tutorial' )") dbtest_curs.execute("SELECT * FROM postgresqldotorg") dbtest_row = dbtest_curs.fetchone() print(f"{dbtest_row}") dbtest_curs.execute("INSERT INTO postgresqldotorg ( page_name ) VALUES ( 'psycopg3_tutorial' )") dbtest_curs.execute("INSERT INTO postgresqldotorg ( page_name ) VALUES ( 'postgresqltutorial.com' )") dbtest_curs.execute("INSERT INTO postgresqldotorg ( page_name ) VALUES ( 'psycopg2.org' )") dbtest_curs.execute("SELECT * FROM postgresqldotorg") dbtest_rows = dbtest_curs.fetchall() print(f"{dbtest_rows}") except (Exception, psycopg2.DatabaseError) as error: print(error)
使用 Python 字典访问
psycopg 的一个便捷功能是能够按列名访问数据。
以下代码片段说明了按列访问 SELECT 语句的结果。
#!/usr/bin/env python # # Small script to show Pyscopg2 cursor with dictionary # import psycopg2 # note the extras import import psycopg2.extras try: conn = psycopg2.connect("dbname='dbtest' user='dbuser' host='localhost' password='dbpass'") except: print("I am unable to connect to the database") # pass the DictCursor factory to the cursor with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as curs: try: curs.execute("SELECT * FROM postgresqldotorg") pg_rows = curs.fetchall() # loop on the results for pg_row in pg_rows: # access the column by name print(f"{pg_row['page_name']}") except (Exception, psycopg2.DatabaseError) as error: print(error)
资源
本文最初以 使用 Python 和 Psycopg2 访问 PostgreSQL 为标题发布:Python 和 PostgreSQL 的组合非常强大,尤其是在使用 Psycopg2 驱动程序时。作者:Joshua D. Drake,2005 年 8 月 26 日。