Python 的資料函式庫生態相當豐富,提供各種不同層級的函式庫,從底層的 DB-API2 到高階的 ORM,讓開發者能依專案需求彈性運用。對於簡單的資料儲存,sqlite3 作為標準函式庫提供輕量級的解決方案。而 SQLAlchemy 則以 Data Mapper 模式提供更進階的 ORM 功能,並支援多種資料函式庫後端。針對 Web 開發,Django 框架內建的 Django ORM 簡化了資料函式庫操作,而輕量級的 peewee 則適合資源有限的環境。選擇合適的函式庫能有效提升開發效率,並確保資料函式庫操作的安全性與效能。

資料持久化中的資料函式庫函式庫

在資料持久化的領域中,Python 提供了多種資料函式庫函式庫來滿足不同的需求。這些函式庫不僅支援多種資料函式庫系統,還提供了不同的抽象層級和操作介面,使得開發者能夠根據專案需求選擇最合適的工具。

資料函式庫後端與 dbm 函式庫

dbm 函式庫是一個用於儲存鍵值對的簡單資料函式庫,它將資料儲存在磁碟上的雜湊表中。dbm 的實作取決於所使用的後端,包括 gdbm、ndbm 和 “dumb” 後端。其中,“dumb” 後端是用 Python 實作的,而其他兩種後端則需要額外的支援。值得注意的是,使用 ndbm 後端時,值的大小存在上限。此外,當以寫入模式開啟資料函式庫檔案時,除非使用特定的開啟模式(如 ruwu),否則檔案會被鎖定。

import shelve

with shelve.open('my_shelf') as s:
    s['d'] = {'key': 'value'}

s = shelve.open('my_shelf', 'r')
print(s['d'])  # 輸出:{'key': 'value'}

內容解密:

  1. shelve.open('my_shelf'):開啟一個名為 my_shelf 的 shelf 資料函式庫。如果資料函式庫不存在,則會自動建立。
  2. s['d'] = {'key': 'value'}:將字典 {'key': 'value'} 儲存到 shelf 資料函式庫中,鍵為 'd'
  3. shelve.open('my_shelf', 'r'):以唯讀模式開啟 shelf 資料函式庫。
  4. s['d']:從 shelf 資料函式庫中讀取鍵為 'd' 的值。

Python 資料函式庫 API(DB-API2)

Python 資料函式庫 API(DB-API2)定義了 Python 中資料庫存取的標準介面。幾乎所有的 Python 資料函式庫驅動程式都遵循這個介面,因此開發者可以根據需要選擇合適的驅動程式來查詢資料函式庫,例如 sqlite3、psycopg2 和 MySQL-python。

資料函式庫抽象層(DAL)與物件關聯對映(ORM)

為了簡化資料函式庫操作,許多函式庫提供了資料函式庫抽象層(DAL)和物件關聯對映(ORM)。DAL 將 SQL 語法和資料型別抽象化,提供了一個更簡潔的 API。ORM 則進一步將資料函式庫表格對映為 Python 物件,使得開發者能夠以物件導向的方式操作資料函式庫。

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

engine = create_engine('sqlite:///example.db')
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

new_user = User(name='John Doe', age=30)
session.add(new_user)
session.commit()

內容解密:

  1. declarative_base():建立一個基礎類別,用於定義 ORM 模型。
  2. Column(Integer, primary_key=True):定義一個整數型別的主鍵欄位。
  3. create_engine('sqlite:///example.db'):建立一個連線到 SQLite 資料函式庫的引擎。
  4. sessionmaker(bind=engine):建立一個 Session 類別,用於建立與資料函式庫的會話。
  5. session.add(new_user):將新的 User 物件新增到會話中。
  6. session.commit():提交會話中的變更到資料函式庫。

常見的資料函式庫函式庫

下表列出了一些常見的 Python 資料函式庫函式庫,以及它們的特點和授權條款:

函式庫名稱授權條款使用理由
sqlite3PSFL標準函式庫,適合低流量網站或原型開發
SQLAlchemyMIT提供 Data Mapper 模式,具有 ORM 和低階 API
Django ORMBSD與 Django 緊密結合,提供 Active Record 模式
peeweeMIT簡單的 Active Record 模式,支援多種資料函式庫
PonyORMAGPLv3直觀的生成器語法,支援圖形化資料模型編輯器
SQLObjectLGPL最早使用 Active Record 模式的 Python 函式庫之一
RecordsISC簡單的 SQL 查詢介面,支援多種輸出格式

這些函式庫各有其特點和適用場景,開發者可以根據專案需求選擇最合適的工具。無論是簡單的鍵值儲存還是複雜的關聯式資料函式庫,Python 都提供了豐富的選擇。

資料函式庫函式庫比較與實作範例

在Python的資料函式庫操作中,有多種函式庫可供選擇,每種都有其特點與適用場景。本文將重點介紹sqlite3SQLAlchemy這兩種常見的資料函式庫函式庫,並透過例項程式碼展示其用法。

SQLite與sqlite3

SQLite是一種輕量級的資料函式庫系統,其資料函式庫檔案通常以.db為副檔名。sqlite3是Python內建的SQLite資料函式庫介面模組,能夠輕易地建立、操作SQLite資料函式庫。

使用sqlite3建立與操作資料函式庫

以下是一個簡單的使用sqlite3建立資料函式庫並進行基本操作的例子:

import sqlite3

# 建立資料函式庫連線
db = sqlite3.connect('cheese_emporium.db')

# 建立一個名為cheese的表格
db.execute('CREATE TABLE cheese(id INTEGER, name TEXT)')

# 插入多筆資料到cheese表格中
db.executemany(
    'INSERT INTO cheese VALUES (?, ?)',
    [(1, 'red leicester'),
     (2, 'wensleydale'),
     (3, 'cheddar'),
    ]
)

# 提交變更
db.commit()

# 關閉資料函式庫連線
db.close()

內容解密:

  1. 建立資料函式庫連線:使用sqlite3.connect()函式建立與SQLite資料函式庫的連線,若指定的資料函式庫檔案不存在,則會自動建立一個新的檔案。
  2. 執行SQL指令:透過db.execute()方法執行SQL指令,如建立表格、插入資料等。
  3. executemany()方法:用於執行多次相同的SQL指令,但每次使用不同的引數,這裡用於插入多筆資料到cheese表格中。
  4. 提交變更:使用db.commit()將對資料函式庫所做的變更儲存。
  5. 關閉連線:操作完成後,使用db.close()關閉與資料函式庫的連線。

SQLAlchemy

SQLAlchemy是一個功能強大的SQL工具包和物件關係對映(ORM)系統,支援多種資料函式庫後端。它採用Martin Fowler的Data Mapper模式,而非常見的Active Record模式。

使用SQLAlchemy進行物件關係對映

以下是一個使用SQLAlchemy定義多對多關係的例子:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Date, Integer, String, Table, ForeignKey
from sqlalchemy.orm import relationship

Base = declarative_base()

class Customer(Base):
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)

    def __repr__(self):
        return "<Customer(name='%s')>" % (self.name)

# 定義一個未對映的表格,用於多對多關係
purchases_cheeses = Table(
    'purchases_cheeses', Base.metadata,
    Column('purch_id', Integer, ForeignKey('purchases.id', primary_key=True)),
    Column('cheese_id', Integer, ForeignKey('cheeses.id', primary_key=True))
)

class Cheese(Base):
    __tablename__ = 'cheeses'
    id = Column(Integer, primary_key=True)
    kind = Column(String, nullable=False)
    purchases = relationship(
        'Purchase', secondary='purchases_cheeses', back_populates='cheeses'
    )

    def __repr__(self):
        return "<Cheese(kind='%s')>" % (self.kind)

class Purchase(Base):
    __tablename__ = 'purchases'
    id = Column(Integer, primary_key=True)
    customer_id = Column(Integer, ForeignKey('customers.id', primary_key=True))
    purchase_date = Column(Date, nullable=False)
    customer = relationship('Customer')
    cheeses = relationship(
        'Cheese', secondary='purchases_cheeses', back_populates='purchases'
    )

    def __repr__(self):
        return ("<Purchase(customer='%s', dt='%s')>" %
                (self.customer.name, self.purchase_date))

內容解密:

  1. 宣告式基礎(Declarative Base)declarative_base()建立了一個基礎類別,用於定義對映到資料函式庫表格的類別。
  2. 定義表格與欄位:每個類別(如Customer, Cheese, Purchase)定義了一個資料函式庫表格及其欄位。
  3. 多對多關係:透過定義一個未對映的表格purchases_cheeses來實作CheesePurchase之間的多對多關係。
  4. relationship()函式:用於定義類別之間的關係,如一對多或多對多,並可透過back_populates引數實作雙向關聯。

建立資料函式庫與進行互動

from sqlalchemy import create_engine
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sess = Session()

# 建立物件並加入session
leicester = Cheese(kind='Red Leicester')
camembert = Cheese(kind='Camembert')
sess.add_all((camembert, leicester))
cat = Customer(name='Cat')
sess.add(cat)
sess.commit()

內容解密:

  1. 建立引擎(Engine):使用create_engine()建立一個連線到特定資料函式庫的引擎,這裡使用的是SQLite記憶體資料函式庫。
  2. 建立所有表格:呼叫Base.metadata.create_all(engine)來在資料函式庫中建立所有定義的表格。
  3. 建立Session:透過sessionmaker建立一個與引擎繫結的Session類別,用於進行資料函式庫操作。
  4. 新增資料:建立物件(如Cheese, Customer),並透過Session的add()add_all()方法將其加入至Session中,最後呼叫commit()提交變更。

本文介紹了Python中兩種重要的資料函式庫操作函式庫:sqlite3SQLAlchemy。透過實際範例展示瞭如何使用這兩個函式庫進行資料函式庫的操作和管理。無論是簡單的SQLite操作還是複雜的ORM對映,Python都提供了強大的工具來支援開發者的需求。

資料函式庫函式庫比較與實作

在軟體開發領域中,資料函式庫的存取與管理是至關重要的環節。不同的程式框架提供了各自的 ORM(Object-Relational Mapping)工具,以簡化資料函式庫的操作流程。本文將探討三種流行的 Python ORM 工具:SQLAlchemy、Django ORM 和 peewee,並透過例項程式碼來展示其使用方法與特性。

SQLAlchemy:彈性與強大的 ORM 工具

SQLAlchemy 是 Python 中最為廣泛使用的 ORM 函式庫之一,其設計理念是提供一個全面且彈性的資料庫存取介面。以下是一個使用 SQLAlchemy 建立資料函式庫表格並進行操作的範例:

import datetime
from sqlalchemy import create_engine, Column, Integer, Date, ForeignKey, Table
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

# 定義多對多關係的中間表
purchases_cheeses = Table('purchases_cheeses', Base.metadata,
                          Column('purchase_id', Integer, ForeignKey('purchases.id')),
                          Column('cheese_id', Integer, ForeignKey('cheeses.id'))
                          )

class Cheese(Base):
    __tablename__ = 'cheeses'
    id = Column(Integer, primary_key=True)
    kind = Column(String)

class Customer(Base):
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True)
    name = Column(String)

class Purchase(Base):
    __tablename__ = 'purchases'
    id = Column(Integer, primary_key=True)
    purchase_date = Column(Date)
    customer_id = Column(Integer, ForeignKey('customers.id'))
    customer = relationship("Customer")
    cheeses = relationship("Cheese", secondary=purchases_cheeses)

#### 內容解密:
- 首先定義了三個類別:`Cheese`、`Customer``Purchase`,分別對應資料函式庫中的三張表格
- 使用 `Table` 物件定義了多對多關係的中間表 `purchases_cheeses`。
- `Purchase` 類別透過 `relationship``Cheese` 類別建立了多對多的關係並指定 `secondary` 引數為中間表

d = datetime.date(1971, 12, 18)
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
sess = Session()

cat = Customer(name='Cat')
camembert = Cheese(kind='Camembert')
p = Purchase(purchase_date=d, customer=cat)
p.cheeses.append(camembert)
sess.add(p)
sess.commit()

#### 內容解密:
- 建立了一個 `Customer` 物件和一個 `Cheese` 物件
- 建立了一個 `Purchase` 物件並將其與 `Customer` 物件關聯同時新增了一個 `Cheese` 物件到 `Purchase`
-`Purchase` 物件加入 session 並提交以儲存到資料函式庫中

Django ORM:緊密整合的資料函式庫介面

Django ORM 是 Django 網路框架的一部分,提供了一個方便的資料庫存取介面。以下是一個使用 Django ORM 的範例:

from django.db import models

class Cheese(models.Model):
    type = models.CharField(max_length=30)

class Customer(models.Model):
    name = models.CharField(max_length=50)

class Purchase(models.Model):
    purchase_date = models.DateField()
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    cheeses = models.ManyToManyField(Cheese)

#### 內容解密:
- 定義了三個模型類別:`Cheese`、`Customer``Purchase`,分別對應資料函式庫中的表格
- 使用 `ForeignKey``ManyToManyField` 建立模型間的關係

leicester = Cheese.objects.create(type='Red Leicester')
camembert = Cheese.objects.create(type='Camembert')
doug = Customer.objects.create(name='Douglas')

import datetime
now = datetime.datetime(1971, 12, 18, 20)
day = datetime.timedelta(1)
p = Purchase.objects.create(purchase_date=now - day, customer=doug)
p.cheeses.add(camembert, leicester)

#### 內容解密:
- 建立了兩個 `Cheese` 物件和一個 `Customer` 物件
- 建立了一個 `Purchase` 物件並將其與 `Customer` 物件關聯同時新增了兩個 `Cheese` 物件到 `Purchase`

peewee:輕量級的 ORM 解決方案

peewee 是一個輕量級的 ORM 函式庫,旨在提供簡單直接的資料函式庫操作。以下是一個使用 peewee 的範例:

import peewee

database = peewee.SqliteDatabase('peewee.db')

class BaseModel(peewee.Model):
    class Meta:
        database = database

class Customer(BaseModel):
    name = peewee.TextField()

class Purchase(BaseModel):
    purchase_date = peewee.DateField()
    customer = peewee.ForeignKeyField(Customer, related_name='purchases')

class Cheese(BaseModel):
    kind = peewee.TextField()

class PurchaseCheese(BaseModel):
    purchase = peewee.ForeignKeyField(Purchase)
    cheese = peewee.ForeignKeyField(Cheese)

database.create_tables([Customer, Purchase, Cheese, PurchaseCheese])

#### 內容解密:
- 定義了四個模型類別:`Customer`、`Purchase`、`Cheese``PurchaseCheese`,其中 `PurchaseCheese` 用於實作多對多關係
- 使用 `ForeignKeyField` 建立模型間的關係

leicester = Cheese.create(kind='Red Leicester')
camembert = Cheese.create(kind='Camembert')
cat = Customer.create(name='Cat')

#### 內容解密:
- 建立了兩個 `Cheese` 物件和一個 `Customer` 物件