Python訪問PostgreSQL數(shù)據(jù)庫詳細操作
一、前言
1.1 概述
Python 是一種高級、通用的解釋型編程語言,以其優(yōu)雅、準確、 簡單的語言特性,在云計算、Web 開發(fā)、自動化運維、數(shù)據(jù)科學(xué)以及機器學(xué)習(xí)等人工智能領(lǐng)域獲得了廣泛應(yīng)用。Python 定義了連接和操作數(shù)據(jù)庫的標準接口 Python DB API。不同的數(shù)據(jù)庫在此基礎(chǔ)上實現(xiàn)了特定的驅(qū)動,這些驅(qū)動都實現(xiàn)了標準接口。支持PostgreSQL的庫也有不少,從PostgreSQL提供的 WIKI 可以得知,使用得最多的而且最成熟的是Psycopg2。
PostgreSQL 數(shù)據(jù)庫是最常用的關(guān)系型數(shù)據(jù)庫之一,最吸引人的一點是它作為開源數(shù)據(jù)庫且具有可拓展性,能夠提供豐富的應(yīng)用。運用python可以很簡單的建立PostgreSQL 數(shù)據(jù)庫連接,最常見的 Python 驅(qū)動程序就是 psycopg,它完全實現(xiàn)了 Python DB-API 2.0 接口規(guī)范。接下來我們介紹如何通過 psycopg 連接和操作 PostgreSQL 數(shù)據(jù)庫。
1.2 什么是 Psycopg
PostgreSQL可以使用 psycopg 模塊與Python集成,是用于 Python 編程語言的 PostgreSQL 數(shù)據(jù)庫適配器,其是非常小,快速,穩(wěn)定的。 不需要單獨安裝此模塊,因為默認情況下它會隨著Python一起發(fā)布。首先,我們需要安裝 Python 。Python 可以通過官方網(wǎng)站下載,安裝之后可以通過以下命令查看版本信息:
Python -v
然后通過 pip 安裝最新的 psycopg:
# 適用于Python2 pip install --upgrade psycopg2 # 適用于Python3 pip3 install --upgrade psycopg2
也可以在pycharm中查找psycopg2安裝包:
想要使用psycopg2,必須用import語句導(dǎo)入該包:
import psycopg2
二、操作 PostgreSQL
2.1 連接數(shù)據(jù)庫
為了方便開發(fā),在 Pycharm 中新建一個項目 PythonPostgreSQL,然后創(chuàng)建一個數(shù)據(jù)庫連接的配置文件 dbconfig.ini,添加以下內(nèi)容:
[postgresql] host = 127.0.0.1 port = 5432 database = HR user = navicat password = testnavicat
配置文件中存儲了數(shù)據(jù)庫的連接信息:主機、端口、數(shù)據(jù)庫、用戶以及密碼,按照自己的環(huán)境進行配置。要使用 psycopg2 模塊,必須首先創(chuàng)建一個表示數(shù)據(jù)庫的 Connection 對象,然后可以選擇創(chuàng)建可以執(zhí)行所有SQL語句的游標對象。新建一個測試數(shù)據(jù)庫連接的 Python 文件 postgresql_connection.py,示例代碼如下所示:
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) print("Opened database successfully") pass if __name__ == '__main__': main()
上述代碼展示了如何連接到一個現(xiàn)有的數(shù)據(jù)庫。如果數(shù)據(jù)庫不存在,那么它就會被創(chuàng)建,最終將返回一個數(shù)據(jù)庫對象。connection類表示數(shù)據(jù)庫連接對象,是由psycopg2.connect()方法創(chuàng)建。psycopg2.connect() 函數(shù)創(chuàng)建一個新的數(shù)據(jù)庫會話并且返回一個連接對象,以執(zhí)行 DML、DDL、DQL 等數(shù)據(jù)庫事務(wù)。該函數(shù)的參數(shù)為:
參數(shù) | 說明 |
---|---|
database | 要連接的數(shù)據(jù)庫名稱 |
user | 連接數(shù)據(jù)庫的用戶名 |
password | 連接數(shù)據(jù)庫的密碼 |
host | 數(shù)據(jù)庫地址,一般為 localhost,或者主機的IP地址 |
port | 端口,默認為5432 |
connection提供了如下常用的數(shù)據(jù)庫操作:
數(shù)據(jù)庫操作 | 說明 |
---|---|
commit() | 提交任何未提交的事務(wù)到數(shù)據(jù)庫 |
rollback() | 回滾 |
close() | 關(guān)閉數(shù)據(jù)庫。如果關(guān)閉數(shù)據(jù)庫時仍有未提交的事務(wù),則執(zhí)行回滾操作 |
為了執(zhí)行任何 SQL 事務(wù)或語句,我們需要實現(xiàn)游標 cursor 類,用來里執(zhí)行 PostgreSQL 命令,其由 connection.cursor() 方法創(chuàng)建。它們在整個生命周期內(nèi)都綁定到連接,并且所有命令都在連接包裝的數(shù)據(jù)庫會話的上下文中執(zhí)行,退出程序時也會關(guān)閉光標。
cur = conn.cursor();
有了cursor對象,就可以操作數(shù)據(jù)庫了,cursor 提供了 execute 方法用來執(zhí)行SQL語句,詳細方法繼續(xù)往下看。
2.2 異常處理
使用psycopg2的 Error 進行異常捕獲,能捕獲到sql執(zhí)行時期的所有異常。處理此異常的最佳方法是將 conn 對象和 cursor 的閉包放在 finally 塊中,以防我們的連接出現(xiàn)錯誤。另外,如果數(shù)據(jù)庫沒有連接,并且對連接對象應(yīng)用了 close 方法,我們的 finally 塊中就會出錯。下面代碼中表test是庫中不存的表,執(zhí)行sql后會報異常,經(jīng)過異常捕獲后非常美觀,不影響程序運行;
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): global connection try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) print("連接成功,PostgreSQL 服務(wù)器版本:") except (Exception, DatabaseError) as e: print("連接 PostgreSQL 失?。?, e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() print("PostgreSQL 數(shù)據(jù)庫連接已關(guān)閉。") pass if __name__ == '__main__': main()
2.3 創(chuàng)建表
當(dāng)數(shù)據(jù)庫建立連接成功后,可以通過執(zhí)行 CREATE TABLE 和 DROP TABLE 語句執(zhí)行DDL 事務(wù)來創(chuàng)建和刪除數(shù)據(jù)表。我們創(chuàng)建一個新的 Python 文件 postgresql_create.py 在數(shù)據(jù)庫中創(chuàng)建一個表,示例代碼如下所示:
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) # 創(chuàng)建一個游標 cur = connection.cursor() # 定義 SQL 語句 sql = """ create table createtabletest ( id serial primary key, name character varying(10) not null unique, created_at timestamp not null ) """ # 執(zhí)行 SQL 命令 cur.execute(sql) # 關(guān)閉游標 cur.close() # 提交事務(wù) connection.commit() print("操作成功!") except (Exception, DatabaseError) as e: print("操作失?。?, e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() print("PostgreSQL 數(shù)據(jù)庫連接已關(guān)閉。") pass if __name__ == '__main__': main()
同樣是先連接數(shù)據(jù)庫,然后利用游標對象的 execute() 方法執(zhí)行 SQL 命令創(chuàng)建表。commit 方法用于提交事務(wù)修改,如果不執(zhí)行該操作不會真正創(chuàng)建表,因為 psycopg2 連接 PostgreSQL 默認不會自動提交(autocommit)。執(zhí)行該腳本的結(jié)果如下:
操作成功!
PostgreSQL 數(shù)據(jù)庫連接已關(guān)閉。
如果 createtabletest 表已經(jīng)存在,將會返回以下錯誤:
操作失敗: relation "createtabletest" already exists
2.4 INSERT 操作
我們將使用 INSERT 命令執(zhí)行 DML 事務(wù),可以將一些數(shù)據(jù)添加到表中。Python 中游標對象的 execute() 方法用于執(zhí)行 SQL 語句,該方法可以接收參數(shù)實現(xiàn)預(yù)編譯語句。以下顯示了我們?nèi)绾卧谝褎?chuàng)建的表中插入記錄,示例代碼如下所示:
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) # 創(chuàng)建一個游標 cur = connection.cursor() # 定義 SQL 語句 sql = "insert into createtabletest(name, created_at) values (%s, %s) RETURNING id" # 執(zhí)行 SQL 命令 cur.execute(sql, ('tony', '2023-04-15 00:56:00')) cur.execute(sql, ('zhangSan', '2023-04-15 00:56:00')) cur.execute(sql, ('liSi', '2023-04-15 00:56:00')) cur.execute(sql, ('wangWu', '2023-04-15 00:56:00')) # 獲取 id id = cur.fetchone()[0] # 提交事務(wù) connection.commit() print("操作成功! 用戶 id:", id) # 關(guān)閉游標 cur.close() except (Exception, DatabaseError) as e: print("操作失?。?, e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() print("PostgreSQL 數(shù)據(jù)庫連接已關(guān)閉。") pass if __name__ == '__main__': main()
上面示例中,sql 變量中的百分號(%)是占位符,這些占位符的值在 execute() 方法中進行替換;游標對象的 fetchone 方法用于返回一行結(jié)果,這里用于獲取 RETURNING id 返回的用戶 id。
2.5 SELECT 操作
當(dāng)我們創(chuàng)建表完成并插入數(shù)據(jù)后,可以執(zhí)行一個 SELECT 事務(wù)來查看插入的數(shù)據(jù)。游標對象提供了三種獲取返回結(jié)果的方法。如下表所示:
方法 | 說明 |
---|---|
fetchone() | 獲取下一行數(shù)據(jù)。當(dāng)沒有更多的數(shù)據(jù)是可用時,返回null |
fetchmany([size=cursor.arraysize]) | 獲取下一組數(shù)據(jù)行。當(dāng)沒有找到記錄,返回空列表。 |
fetchall() | 獲取所有查詢結(jié)果,返回值為tuple列表??招袝r則返回空列表 |
我們創(chuàng)建一個新的文件來展示如何獲取并顯示在上面的例子中創(chuàng)建的記錄,示例代碼如下所示:
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) # 創(chuàng)建一個游標 cur = connection.cursor() # 定義 SQL 語句 sql = "select id, name, created_at from createtabletest" # 執(zhí)行 SQL 命令 cur.execute(sql) print("用戶數(shù)量:", cur.rowcount) # 獲取結(jié)果 user = cur.fetchone() while user is not None: print(user) user = cur.fetchone() # 關(guān)閉游標 cur.close() except (Exception, DatabaseError) as e: print("操作失?。?, e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() pass if __name__ == '__main__': main()
在上面示例中,游標對象的 rowcount 屬性代表了返回的數(shù)據(jù)行數(shù),fetchone() 方法返回一行數(shù)據(jù)或者 None,while 循環(huán)用于遍歷和打印查詢結(jié)果。
2.6 UPDATE 操作
更新數(shù)據(jù)的流程跟之前的查詢、插入類似,可以使用UPDATE語句來獲取并顯示更新的記錄,psycopg2支持單條數(shù)據(jù)更新及批量更新,不過需要注意的是,PostgreSQL的數(shù)據(jù)被修改后,直接SELECT的話,數(shù)據(jù)并不會根據(jù)主鍵自動排序。示例代碼如下所示:
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) # 創(chuàng)建一個游標 cur = connection.cursor() # 定義 SQL 語句 sql = "update created_at set name = %s where id = %s" # 執(zhí)行 SQL 命令 cur.execute(sql, ('tom', 1)) # 獲取 id rows = cur.rowcount # 提交事務(wù) connection.commit() print("操作成功! 更新行數(shù):", rows) # 再次查詢數(shù)據(jù) sql = "select id, name, created_at from createtabletest where id = 1" cur.execute(sql) user = cur.fetchone() print(user) # 關(guān)閉游標 cur.close() except (Exception, DatabaseError) as e: print("操作失敗:", e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() pass if __name__ == '__main__': main()
2.7 DELETE 操作
刪除操作很簡單,與更新數(shù)據(jù)的操作基本相同,只需要將 UPDATE 語句替換成 DELETE 語句,就可以刪除表中的數(shù)據(jù)。示例代碼如下所示:
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) # 創(chuàng)建一個游標 cur = connection.cursor() # 定義 SQL 語句 sql = "delete from createtabletest where id = %s" # 執(zhí)行 SQL 命令 cur.execute(sql, (1,)) rows = cur.rowcount # 提交事務(wù) connection.commit() print("操作成功! 刪除行數(shù):", rows) # 關(guān)閉游標 cur.close() except (Exception, DatabaseError) as e: print("操作失?。?, e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() pass if __name__ == '__main__': main()
在 MySQ 中,TRUNCATE TABLE 語句會將表的數(shù)據(jù)清空,而且會重置自增主鍵的計數(shù)。但是在 PostgreSQL 中,必須要在這個語句后面添加 RESTART IDENTITY,才能將主鍵重置,不然就只會清空表。
2.8 事務(wù)管理
在前面的示例中,需要使用 connection.commit() 提交對 PostgreSQL 數(shù)據(jù)庫執(zhí)行的修改,這是因為 psycopg2 默認沒有打開自動提交功能,我們也可以利用連接對象的 autocommit 屬性設(shè)置是否自動提交。
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) # 打印和設(shè)置自動提交 print('默認 autocommit:', connection.autocommit) connection.autocommit = True print('新的 autocommit:', connection.autocommit) # 創(chuàng)建一個游標 cur = connection.cursor() # 定義 SQL 語句 sql = " insert into createtabletest(name, created_at) values (%s, %s) RETURNING id " # 執(zhí)行 SQL 命令 cur.execute(sql, ('tony', '2020-06-08 11:00:00')) # 獲取 id id = cur.fetchone()[0] print("操作成功! 用戶 id:", id) # 關(guān)閉游標 cur.close() except (Exception, DatabaseError) as e: print("操作失?。?, e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() print("PostgreSQL 數(shù)據(jù)庫連接已關(guān)閉。") pass if __name__ == '__main__': main()
通過 connection.autocommit 設(shè)置了自動提交,所以 INSERT 語句插入數(shù)據(jù)之后不需要再執(zhí)行 commit 操作。如果一個事務(wù)中包含多個數(shù)據(jù)庫操作,還是應(yīng)該在事務(wù)的最后統(tǒng)一執(zhí)行提交,并且在異常處理部分通過連接對象的 rollback() 方法回滾部分完成的事務(wù)。
另一種管理事務(wù)的方法是使用 with 語句,這樣可以避免手動的資源管理和事務(wù)操作。
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 with 語句管理事務(wù) with psycopg2.connect(**db_config) as connection: # 創(chuàng)建一個游標 with connection.cursor() as cur: # 插入數(shù)據(jù) sql = " insert into createtabletest(name, created_at) values (%s, %s) " cur.execute(sql, ('Jason', '2023-04-15 10:30:00')) # 更新數(shù)據(jù) sql = "update createtabletest set created_at = %s where name = %s" cur.execute(sql, ('2023-04-15 11:00:00', 'tony')) sql = " select id, name, created_at from createtabletest " # 查詢數(shù)據(jù) cur.execute(sql) # 獲取結(jié)果 user = cur.fetchone() while user is not None: print(user) user = cur.fetchone() except (Exception, DatabaseError) as e: print("操作失敗:", e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() pass if __name__ == '__main__': main()
在上面示例中,整個事務(wù)包含插入數(shù)據(jù)、更新數(shù)據(jù)以及查詢數(shù)據(jù)三個操作。
2.9 調(diào)用存儲函數(shù)
游標對象的 callproc() 方法可以用于執(zhí)行存儲函數(shù)。我們先創(chuàng)建一個返回用戶數(shù)量的函數(shù) get_user_count:
CREATE OR REPLACE FUNCTION get_user_count() returns int AS $$ DECLARE ln_count int; BEGIN select count(*) into ln_count from users; return ln_count; END; $$ LANGUAGE plpgsql;
接下來創(chuàng)建一個新的文件來展示如何調(diào)用存儲函數(shù):
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 with 語句管理事務(wù) with psycopg2.connect(**db_config) as connection: # 創(chuàng)建一個游標 with connection.cursor() as cur: # 調(diào)用存儲函數(shù) cur.callproc('get_user_count') row = cur.fetchone()[0] print('用戶總數(shù):', row) except (Exception, DatabaseError) as e: print("操作失敗:", e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() pass if __name__ == '__main__': main()
callproc() 方法調(diào)用存儲函數(shù)也可以寫成以下等價的形式:
cur.execute('select * from get_user_count()')
2.10 批量操作
上面示例中提到 python操作 PostgreSql 的操作數(shù)據(jù)基本用法,但這并不能滿足我們操作大量數(shù)據(jù)的美好心愿,在實際使用中,更多的時候需要進行批量的增刪改查操作。批量操作數(shù)據(jù)庫有多種方法,根據(jù)官網(wǎng)的敘述,數(shù)據(jù)批量操作有以下幾種方法:
方法 | 說明 |
---|---|
executemany | 最簡單的一種方法,屬于游標的實例方法 |
execute_batch | 性能好,速度快的方法,屬于類方法 |
execute_values | 官方推薦的方法,但是條件是要批量操作的字段的值必須相同 |
import psycopg2 from psycopg2 import DatabaseError from configparser import ConfigParser from psycopg2.extras import execute_batch # 讀取數(shù)據(jù)庫配置文件,返回一個字典對象 def read_db_config(filename='dbconfig.ini', section='postgresql'): # 創(chuàng)建解析器,讀取配置文件 parser = ConfigParser() parser.read(filename) # 獲取 postgresql 部分的配置 db = {} if parser.has_section(section): items = parser.items(section) for item in items: db[item[0]] = item[1] else: raise Exception('文件 {1} 中未找到 {0} 配置信息!'.format(section, filename)) return db db_config = read_db_config() connection = None def main(): try: # 使用 psycopg2.connect 方法連接 PostgreSQL 數(shù)據(jù)庫 connection = psycopg2.connect(**db_config) # 打印和設(shè)置自動提交 print('默認 autocommit:', connection.autocommit) connection.autocommit = True print('新的 autocommit:', connection.autocommit) # 創(chuàng)建一個游標 cursor = connection.cursor() # 定義 SQL 語句 sql = " insert into createtabletest(name, created_at) values (%s, %s) RETURNING id " data = [['member%d' % x, '2023-04-16 11:%d:00' % x] for x in range(0, 60)] # 執(zhí)行 SQL 命令 execute_batch(cursor, sql, data, page_size=len(data)) # 獲取 id id = cursor.fetchone()[0] print("操作成功! 用戶 id:", id) # 關(guān)閉游標 cursor.close() except (Exception, DatabaseError) as e: print("操作失敗:", e) finally: # 釋放數(shù)據(jù)庫連接 if connection is not None: connection.close() print("PostgreSQL 數(shù)據(jù)庫連接已關(guān)閉。") pass if __name__ == '__main__': main()
總結(jié)
到此這篇關(guān)于Python訪問PostgreSQL數(shù)據(jù)庫的文章就介紹到這了,更多相關(guān)Python訪問PostgreSQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python采用Django開發(fā)自己的博客系統(tǒng)
這篇文章主要為大家詳細介紹了Python采用Django開發(fā)自己的博客系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-08-08Pycharm中pyqt工具配置(Qt Designer、PyUIC、PyRCC)
Pycharm中進行擴展工具設(shè)置,從而實現(xiàn)在pycharm中打開Qt Designer、Ui文件生成Py文件、資源文件生成Py文件三個功能,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07