Psycopg2 教程

来自 PostgreSQL Wiki
跳转到导航跳转到搜索

为 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 驱动程序,正在积极开发中。它专为多线程应用程序而设计,并管理自己的连接池。

本文讨论了基础知识。

  1. 使用 Psycopg2 连接到 PostgreSQL
  2. 执行基本查询
  3. 事务范围
  4. 使用 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 日。