WeHelp
PostgreSQL 是一套免費、開源的強大物件關聯式資料庫管理系統,適合處理複雜的結構化資料與高負載應用程式。
  1. PostgreSQL 下載安裝
  2. 啟動、連線測試
  3. Database 管理
  4. Schema 管理
  5. SQL 資料表管理
  6. SQL 資料管理
  7. SQL 資料取得、篩選
  8. 欄位的資料型態
  9. 資料交易簡介、操作
  10. 使用者管理
  11. Python 程式連線
  12. Node.js 程式連線
  13. C# 程式連線
Python 程式連線
Python 通常透過 PostgreSQL 驅動程式連線資料庫,常用套件是 **`psycopg`**(新版,原名 psycopg3)。 ## 1. 安裝 PostgreSQL 驅動程式 ```bash pip install "psycopg[binary]" ``` 也可以使用較舊的 `psycopg2`: ```bash pip install psycopg2-binary ``` 以下以新版 `psycopg` 為例。 --- ## 2. 建立資料庫連線 ```python import psycopg conn = psycopg.connect( host="localhost", port=5432, dbname="mydb", user="postgres", password="mypassword" ) print("資料庫連線成功") conn.close() ``` 常見連線參數: | 參數 | 說明 | |---|---| | `host` | PostgreSQL 伺服器位址 | | `port` | 預設為 `5432` | | `dbname` | 資料庫名稱 | | `user` | 使用者名稱 | | `password` | 密碼 | 也可以使用連線字串: ```python conn = psycopg.connect( "postgresql://postgres:mypassword@localhost:5432/mydb" ) ``` 正式環境不建議把密碼直接寫在程式碼中,應使用環境變數: ```python import os import psycopg conn = psycopg.connect( host=os.getenv("PGHOST", "localhost"), port=os.getenv("PGPORT", "5432"), dbname=os.getenv("PGDATABASE", "mydb"), user=os.getenv("PGUSER", "postgres"), password=os.getenv("PGPASSWORD") ) ``` --- ## 3. 建立資料表並執行 SQL 透過 `cursor()` 建立游標,再使用 `execute()` 執行 SQL: ```python import psycopg with psycopg.connect( host="localhost", port=5432, dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.execute(""" CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(200) UNIQUE NOT NULL ) """) # with 區塊結束時,若沒有例外會自動 commit ``` 使用 `with` 可以自動處理: - 關閉游標 - 提交交易 `commit` - 發生錯誤時回滾 `rollback` - 關閉資料庫連線 --- ## 4. 新增資料 ### 使用參數化查詢 ```python import psycopg with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.execute( """ INSERT INTO users (name, email) VALUES (%s, %s) """, ("王小明", "ming@example.com") ) ``` `%s` 是參數佔位符,實際值放在第二個參數中。 不要使用字串串接 SQL: ```python # 不建議,可能造成 SQL Injection name = "王小明" sql = f"INSERT INTO users (name) VALUES ('{name}')" ``` 應使用參數化方式: ```python cur.execute( "INSERT INTO users (name) VALUES (%s)", (name,) ) ``` 注意:單一參數的 tuple 必須加逗號,例如: ```python (name,) ``` --- ## 5. 查詢資料 使用 `SELECT` 查詢資料後,可以使用不同方法取得結果。 ### 取得一筆資料:`fetchone()` ```python with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.execute( "SELECT id, name, email FROM users WHERE id = %s", (1,) ) row = cur.fetchone() if row is not None: print("ID:", row[0]) print("姓名:", row[1]) print("Email:", row[2]) else: print("找不到資料") ``` 查詢結果通常是 tuple: ```python (1, '王小明', 'ming@example.com') ``` --- ### 取得多筆資料:`fetchall()` ```python with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.execute( "SELECT id, name, email FROM users ORDER BY id" ) rows = cur.fetchall() for row in rows: print(row) ``` --- ### 逐筆讀取資料 資料量很大時,不一定要一次使用 `fetchall()`,可以直接迭代 cursor: ```python with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.execute("SELECT id, name, email FROM users") for row in cur: user_id, name, email = row print(user_id, name, email) ``` --- ### 取得欄位名稱 如果希望取得字典格式的資料,可以使用 `dict_row`: ```python import psycopg from psycopg.rows import dict_row with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword", row_factory=dict_row ) as conn: with conn.cursor() as cur: cur.execute("SELECT id, name, email FROM users") rows = cur.fetchall() for row in rows: print(row["id"], row["name"], row["email"]) ``` 結果類似: ```python { "id": 1, "name": "王小明", "email": "ming@example.com" } ``` --- ## 6. 更新與刪除資料 ### 更新資料 ```python with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.execute( """ UPDATE users SET email = %s WHERE id = %s """, ("new@example.com", 1) ) print("更新筆數:", cur.rowcount) ``` ### 刪除資料 ```python with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.execute( "DELETE FROM users WHERE id = %s", (1,) ) print("刪除筆數:", cur.rowcount) ``` --- ## 7. 手動處理交易 如果不使用 `with`,需要自行提交或回滾: ```python import psycopg conn = psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) try: with conn.cursor() as cur: cur.execute( "INSERT INTO users (name, email) VALUES (%s, %s)", ("李小華", "hua@example.com") ) cur.execute( "UPDATE users SET name = %s WHERE email = %s", ("李小華", "hua@example.com") ) conn.commit() print("交易成功") except Exception as e: conn.rollback() print("交易失敗,已回滾:", e) finally: conn.close() ``` 交易原則: - `commit()`:確認並保存修改 - `rollback()`:取消尚未提交的修改 - `close()`:關閉連線 --- ## 8. 批次新增資料 可以使用 `executemany()`: ```python users = [ ("小美", "mei@example.com"), ("小強", "qiang@example.com"), ("小芳", "fang@example.com"), ] with psycopg.connect( host="localhost", dbname="mydb", user="postgres", password="mypassword" ) as conn: with conn.cursor() as cur: cur.executemany( """ INSERT INTO users (name, email) VALUES (%s, %s) """, users ) ``` --- ## 9. 完整範例 ```python import psycopg from psycopg.rows import dict_row DB_CONFIG = { "host": "localhost", "port": 5432, "dbname": "mydb", "user": "postgres", "password": "mypassword", "row_factory": dict_row } def main(): with psycopg.connect(**DB_CONFIG) as conn: with conn.cursor() as cur: cur.execute(""" CREATE TABLE IF NOT EXISTS products ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, price NUMERIC(10, 2) NOT NULL ) """) cur.execute( """ INSERT INTO products (name, price) VALUES (%s, %s) RETURNING id """, ("鍵盤", 1290.00) ) product_id = cur.fetchone()["id"] print("新增產品 ID:", product_id) cur.execute( """ SELECT id, name, price FROM products WHERE price >= %s ORDER BY id """, (1000,) ) products = cur.fetchall() for product in products: print(product) if __name__ == "__main__": main() ``` 這個範例示範了: 1. 連線 PostgreSQL 2. 建立資料表 3. 新增資料 4. 使用 `RETURNING` 取得新增資料的 ID 5. 執行查詢 6. 使用 `fetchall()` 取得結果 7. 以字典格式讀取資料 8. 自動提交交易並關閉連線 重點是:使用 `cursor.execute()` 執行 SQL、使用 `fetchone()` 或 `fetchall()` 取得查詢結果,並一律優先使用參數化查詢以避免 SQL Injection。
相關學習地圖、教學課程
Python 資料工程
從 0 開始,成為資料工程師的學習路徑。