17. 数据库支持
17.4 PostgreSQL

基本概念

PostgreSQL 是一个功能强大的开源对象关系数据库管理系统,可以用于存储和管理各种类型的数据,包括结构化数据、半结构化数据和无结构化数据。与 MySQL 类似,PostgreSQL 也被开发人员广泛地应用于各种 Web 项目中。

PostgreSQL,最初被称为 Postgres,起源于 1986 年。它是由加州大学伯克利分校的教授 Michael Stonebraker 领导的一支团队开发的一个研究项目。最早的版本是基于 Ingres 数据库系统的一个改进版本,因此起初被称为 Postgres(Post Ingres)。这个项目的目标是探索新的数据库技术和概念,以改进关系型数据库系统的性能和功能。

在接下来的几年中,Postgres 项目不断演化和改进,其添加了许多新的功能和特性。1996 年,Postgres 项目发布了一个重要的版本,这个版本包括了一个新的查询语言解析器和一个全新的存储系统,这些变化使得 Postgres 更加灵活和强大。

2007 年,Postgres 项目正式更名为 PostgreSQL,以更好地反映其关系型数据库管理系统的性质。此时的 PostgreSQL 已经是一个功能丰富且强大的数据库系统,拥有广泛的社区支持和用户基础。

随着时间的推移,PostgreSQL 不断发展壮大,如今,它已经成为了一款非常受欢迎的开源数据库系统。由于其傲人的稳定性、可扩展性和可定制性,PostgreSQL 已经成为许多企业和组织的首选数据库解决方案之一。

与 MySQL 类似,Python 与 PostgreSQL 的结合也非常紧密。下面,就让我们详细地了解一下 PostgreSQL 在 Python 中的具体使用。

在 Python 中使用 PostgreSQL

作为开发人员,我们其实有多种方式在 Python 中操作 PostgreSQL 数据库,例如:

  1. psycopg2
    psycopg2是一个非常流行的 Python 库,用于连接和操作 PostgreSQL 数据库。它提供了对 PostgreSQL 数据库的高性能访问,支持数据库连接、执行 SQL 查询、事务管理等功能。psycopg2还支持自定义数据类型的转换,使得 Python 开发人员能够轻松地与 PostgreSQL 数据库交互。
  2. SQLAlchemy
    SQLAlchemy是一个强大的 ORM(对象关系映射)库,它支持多种数据库,其中就包括 PostgreSQL。使用SQLAlchemy,开发人员可以在 Python 中定义数据模型并将其映射到 PostgreSQL 数据库表,从而实现面向对象的数据库操作。
  3. DjangoFlask
    DjangoFlask是两个流行的 Python web 框架,它们都有内置的数据库支持,并且可以轻松地与 PostgreSQL 集成。开发人员可以使用这些框架来开发各种强大的 web 应用程序,并使用 PostgreSQL 作为后端数据库存储数据。

本节将以psycopg2库为主,探究 PostgreSQL 在 Python 中的应用。

PostgreSQL 在 Python 中的使用步骤

与 MySQL 类似,如果希望在 Python 中操作 PostgreSQL 数据库,我们一般参考如下的步骤:

安装

我们可以使用pip命令来安装psycopg2库:

pip install psycopg2

安装完成后,我们就可以在 Python 程序中导入psycopg2库了。

import psycopg2

建立数据库连接

操作 PostgreSQL 数据库的第一步,就是建立连接。

import psycopg2
 
connection = psycopg2.connect(
    host="localhost",
    port="5432",
    database="mydatabase",
    user="myuser",
    password="mypassword"
)

我们需要将上例中的"localhost""myuser""mypassword""mydatabase"替换为实际的连接信息。

返回值connection对象表示与 PostgreSQL 服务器的连接。我们可以在此连接上执行后续的数据库操作。

使用游标执行 SQL 查询

在数据库成功连接后,我们就可以使用游标执行 SQL 查询,并与数据库进行交互。

cursor = connection.cursor()
cursor.execute("SELECT column1, column2 FROM mytable")
 
rows = cursor.fetchall()
for row in rows:
    print(row[0], row[1])

在这里,我们执行了一个SELECT查询并获取游标返回的结果集。

关闭游标,关闭连接

与 MySQL 类似,我们在完成数据操作后,需要关闭游标、关闭数据库连接。

cursor.close()
connection.close()

下面让我们详细探究一下psycopg2库中各个方法的使用详情。

语句详解

connect()方法

psycopg2模块中的connect()方法可以帮助开发人员建立与 PostgreSQL 数据库的连接。

import psycopg2
 
# 连接到PostgreSQL数据库
connection = psycopg2.connect(
    host="your_host",
    database="your_database",
    user="your_username",
    password="your_password",
    port="your_port"
)

其中,

  • host:用于指定 PostgreSQL 数据库服务器所在的计算机的主机名或 IP 地址。如果数据库在同一台计算机上运行,我们可以使用localhost127.0.0.1作为值。
  • database:用于指定我们希望连接的 PostgreSQL 服务器中的数据库名称。
  • user:用于提供连接到 PostgreSQL 数据库的用户名。
  • password:用于指定与用户名关联的密码。需要注意的是,除非我们已使用 SSL 加密连接,否则此密码以明文形式发送。
  • port(可选):如果我们的 PostgreSQL 数据库服务器在非默认端口上运行,那么我们就需要在此参数中指定端口。PostgreSQL 的默认端口是5432

cursor()方法

psycopg2模块中,cursor()方法主要用来创建一个游标对象,开发人员可以通过此游标对象来执行后续的 SQL 语句。

cursor()方法的基本语法如下所示:

# 创建游标对象
cursor = connection.cursor(name, cursor_factory)

其中,

  • name:字符串,用来指定游标的名称。在某些情况下--比如处理服务器端游标或使用FETCH命令时,这可能很有用。
  • cursor_factory:用来指定自定义游标工厂类,而不是使用默认的Cursor类。如果我们需要自定义游标的行为,可以使用该参数。注意:自定义游标工厂类必须继承自psycopg2.extensions.cursor类。

举个例子:

import psycopg2
 
connection = psycopg2.connect(
	database="mydb",
	user="myuser",
	password="mypassword",
	host="localhost",
	port="5432")
 
# 创建一个具名游标
cursor = connection.cursor(name="mycursor")
 
# 使用自定义游标工厂创建一个游标
class MyCursor(psycopg2.extensions.cursor):
    # 自定义游标实现...
    pass
 
cursor2 = connection.cursor(cursor_factory=MyCursor)
 
# 使用这些游标执行SQL语句
cursor.execute("SELECT * FROM mytable")
cursor2.execute("SELECT * FROM myothertable")
 
# 关闭这些游标和连接
cursor.close()
cursor2.close()
connection.close()

通常情况下,我们无需为cursor()方法指定参数。

execute()方法

psycopg2模块中的execute()方法用于在 PostgreSQL 数据库中执行 SQL 命令。其语法如下所示。

cursor.execute(sql, vars)

其中,

  • sql:必选参数,用于指定需要执行的 SQL 命令。它既可以是一个简单的 SQL 语句,也可以是一个预处理的 SQL 语句。SQL 可以包含以%s表示的占位符,这些占位符稍后可以用vars参数中提供的实际值来替换。
  • vars:可选参数,用于提供将替换 SQL 语句中占位符的实际值。这些值可以是单个值、元组或字典。如果使用字典,则占位符应与字典中的键对应。

举个例子:

import psycopg2
 
# 建立与PostgreSQL数据库的连接
connection = psycopg2.connect(
	host="localhost",
	database="mydatabase",
	user="myuser",
	password="mypassword")
 
# 创建一个游标对象
cursor = connection.cursor()
 
# 执行一个带有占位符的预处理的SQL语句
cursor.execute(
	"SELECT * FROM employees WHERE age > %s AND salary > %s",
	(30, 50000))
 
# 从结果集中获取所有行
results = cursor.fetchall()
 
# 根据需要处理结果
for row in results:
    print(row)
 
# 关闭游标和数据库连接
cursor.close()
connection.close()

在上面的示例中,我们调用execute()方法来执行一个带有两个占位符(%s)的预处理的 SQL 语句。在执行过程中,实际值(30, 50000)会替换 SQL 语句中的占位符。

fetchone() 方法和 fetchall() 方法

psycopg2模块中的fetchone()方法用于从查询结果集里面检索单个行。它将查询结果集中的下一行作为元组获取,并将游标位置向前移动一行;如果没有更多的行可用,则返回None。其语法如下所示:

cursor.fetchone()

相对应的,fetchall()方法用于从查询结果集中检索出所有行。它将查询结果集中的所有剩余行作为元组的列表获取。其语法如下:

cursor.fetchall()

让我们来看一个例子。

import psycopg2
 
# 连接到数据库
connection = psycopg2.connect(
	database="mydb",
	user="myuser",
	password="mypassword")
 
# 创建一个游标
cursor = connection.cursor()
 
# 执行查询
cursor.execute("SELECT * FROM users")
 
# 获取单个行
one_row = cursor.fetchone()
 
# 获取所有行
rows = cursor.fetchall()
 
# 处理行数据
for row in rows:
    print(row)
 
# 关闭游标和连接
cursor.close()
connection.close()

需要特别注意的是,我们应当谨慎使用fetchall()方法,因为它会一次性将所有行都获取到内存中。如果结果集非常大,这可能会消耗大量的内存。在这种情况下,最好使用循环中的fetchone()来逐个获取行数据,或者使用服务器端游标进行分页。

总结

综上所述,开发人员可以在 Python 中很容易地操作 PostgreSQL 数据库。通过使用类似psycopg2的库,开发人员可以很方便地与 PostgreSQL 数据库进行交互,执行各种 SQL 查询、插入、更新或者删除数据的操作。

除此之外,开发人员还可以使用更高级的 ORM 库来操作 PostgreSQL 数据库。这些内容,我们将在后续章节中进行讲解。