我終於學會了使用python操作postgresql


一 前言

這篇文章不僅適合pgsql,更適合mysql,思路都是一致的,如果讀者學會使用psycopg2操作pgsql,那么使用PyMySQL 操作mysql也是很簡單;本篇文章涵蓋內容廣泛,提供的操作選擇性很多,比如多種數據插入操作,防止sql注入方式,異常處理,sql語句打印處理,顯示行號等操作,一篇文章真的收益匪淺;

二 數據庫連接

2.1 安裝 psycopg2

#  pip install psycopg2

2.2 連接數據庫

每條完整的sql執行步驟如下,讀者應謹記;

  1. 建立連接獲得 connect 對象
  2. 獲得游標對象,一個游標對象可以對數據庫進行執行操作,非線程安全,多個應用會在同一個連接種創建多個光標;
  3. 書寫sql語句
  4. 調用execute()方法執行sql
  5. 抓取數據(可選操作)
  6. 提交事物
  7. 關閉連接
# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象
cursor = conn.cursor()
# sql語句
sql = "SELECT VERSION()"
# 執行語句
cursor.execute(sql)
# 獲取單條數據.
data = cursor.fetchone()
# 打印
print("database version : %s " % data)
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

輸出結果打印出數據庫版本說明連接數據庫成功:

database version : PostgreSQL 11.3, compiled by Visual C++ build 1914, 64-bit 

三 創建表

創建學生表主要有字段id 唯一標識,字段 num 代表學號,字段 name 代表學生姓名;詳細的建表默認規則轉換見附錄

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql = """CREATE TABLE student (
id serial4 PRIMARY KEY, 
num int4,
name varchar(25));"""
# 執行語句
cursor.execute(sql)
print("student table created successfully")
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

四 插入操作

4.1 插入數據姿勢一

知識追尋者提供的第一種防止sql注入的插入數據方式(具有占位符的預編譯sql),重要程度不言而喻;美中不足是字符串類型必須帶上單引號;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="INSERT INTO student (num, name) \
                    VALUES (%s, '%s')" % \
                    (100, 'zszxz')
# 執行語句
cursor.execute(sql)
print("successfully")
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

4.2 插入數據姿勢二(參數分離)

知識追尋者認為下面參數與sql語句分離插入的姿勢更簡便帥氣,也是防止sql注入問題;強烈推薦;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""INSERT INTO student (num, name) VALUES (%s, %s)"""
params = (101, 'zszxz')
# 執行語句
cursor.execute(sql,params)
print("successfully")
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

4.3 插入數據姿勢三(字典)

第三種姿勢也就是是支持字典映射關系插入,使用字典方式的插入數據是根據字典的key進行匹配占位符,強烈推薦;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""INSERT INTO student (num, name) VALUES (%(num)s, %(name)s)"""
params = {'num':102, 'name':'zszxz'}
# 執行語句
cursor.execute(sql,params)
print("successfully")
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

五 查詢操作

5.1 查詢一條數據

使用fetchone()方法可以抓取一條數據, 返回的是元組;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""SELECT * FROM student;"""
# 執行語句
cursor.execute(sql)
# 抓取
row = cursor.fetchone()
print(row)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

輸出結果:

(1, 100, 'zszxz')

5.2 查詢多條數據

  1. 使用fetchmany([size=cursor.arraysize])方法可以抓取多條數據;
  2. 此方法可以多次使用,直到數據庫中沒有數據,此時會返回空列表;
  3. 如果不傳參數,會限制查詢條數,一般就是返回第一條;
# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""SELECT * FROM student;"""
# 執行語句
cursor.execute(sql)
# 抓取
#row = cursor.fetchone()
rows = cursor.fetchmany(2)
print(rows)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

輸出結果:

[(1, 100, 'zszxz'), (2, 101, 'zszxz')]

5.3 查詢全部數據

使用 fetchall() 方法會抓取所有數據;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""SELECT * FROM student;"""
# 執行語句
cursor.execute(sql)
# 抓取
rows = cursor.fetchall()
print(rows)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

輸出結果:

[(1, 100, 'zszxz'), (2, 101, 'zszxz'), (3, 102, 'zszxz')]

5.4 按條件查詢

  1. 帶參查詢讀者應該謹記sql 與 參數 分離
  2. 參數的末尾必須加上逗號
  3. 如果知道返回的數據就一條使用fetchone()方法,如果無特殊要求,否則建議使用fetchall()方法
# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""SELECT * FROM student where id = %s;"""
params = (1,)
# 執行語句
cursor.execute(sql,params)
# 抓取
rows = cursor.fetchall()
print(rows)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

輸出結果:

[(1, 100, 'zszxz')]

六 更新操作

更新操作跟之前的查詢,插入類似,參數對應的文章分清楚即可。

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""update student set name = %s where id = %s  """
params = ('知識追尋者',3,)
# 執行語句
cursor.execute(sql,params)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

七 刪除操作

刪除操作很簡單,看如下代碼,與之前的代碼流程沒什么區別;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""delete from  student where id = %s  """
params = (3,)
# 執行語句
cursor.execute(sql,params)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

八 異常處理

處理 sql 的異常非常重要,知識追尋者這邊使用psycopg2的 Error 進行異常捕獲,能捕獲到sql執行時期的所有異常;下面代碼中表test是庫中不存的表,執行sql后會報異常,經過異常捕獲后非常美觀,不影響程序運行;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""select * from test"""
params = (3,)
try:
    # 執行語句
    cursor.execute(sql,params)
except psycopg2.Error as e:
    print(e)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

執行結果

錯誤:  關系 "test" 不存在
LINE 1: select * from test

九 打印sql

使用cursor.query 可以查看執行的sql語句,方便排查;

# -*- coding: utf-8 -*-
import psycopg2
# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""select * from student"""
try:
    # 執行語句
    cursor.execute(sql,)
    que = cursor.query
    print(que)
except psycopg2.Error as e:
    print(e)
# 事物提交
conn.commit()
# 關閉數據庫連接
cursor.close()
conn.close()

執行結果:

b'select * from student'

十 獲取總條數

使用cursor.rowcount 可以獲得表中所有行總數;

# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""select * from student"""
# 執行語句
cursor.execute(sql)
count = cursor.rowcount
print(count)
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

輸出

2

十一顯示行號

使用cursor.rownumber 可以顯示當前查詢sql獲得數據的行號,每抓取一次光標的索引就會加1;

# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""select * from student """
# 執行語句
cursor.execute(sql)
row_1 = cursor.fetchone()
print(cursor.rownumber)
row_2 = cursor.fetchone()
print(cursor.rownumber)
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

輸出結果:

1
2

十二 顯示執行參數

使用 mogrify(operation[, parameters]) 能夠顯示執行語句的參數綁定結果,返回的是字符串形式;

# 獲得連接
conn = psycopg2.connect(database="python", user="postgres", password="123456", host="127.0.0.1", port="5432")
# 獲得游標對象,一個游標對象可以對數據庫進行執行操作
cursor = conn.cursor()
# sql語句 建表
sql ="""INSERT INTO student (num, name) VALUES (%s, %s)"""
params = (102, '知識追尋者')
# 執行語句
result = cursor.mogrify(sql,params)
print(result.decode('UTF-8'))
cursor.execute(sql,params)
# 事物提交
conn.commit()
# 關閉數據庫連接
conn.close()

執行結果:

INSERT INTO student (num, name) VALUES (102, '知識追尋者')

十三 附錄

支持默認的類型轉換如下,如果想要使用強制類型轉換,詳細的可以參照pgsql官網手冊;

Python PostgreSQL
None NULL
bool bool
float realdouble
intlong smallintintegerbigint
Decimal numeric
strunicode varchartext
buffermemoryviewbytearraybytesBuffer protocol bytea
date date
time time,timetz
datetime timestamp,timestamptz
timedelta interval
list ARRAY
tuple,namedtuple Composite typesIN syntax
dict hstore
Range range
UUID uuid
Anything json
ipaddress inet


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM