ORM 與 SqlAlchemy

物件關係對映器將關聯式資料庫系統對映到物件。如果你不熟悉物件導向的程式設計,請首先閱讀本教程。ORM 獨立於使用哪個關聯式資料庫系統。在 Python 中,你可以與物件進行通訊,ORM 會將其對映到資料庫。在本文中,你將學習使用 SqlAlchemy ORM。

ORM 的功能如下圖所示:

ORM

ORM 物件關係對映。我們使用 ORM 與資料庫通訊,只使用 Python 物件和類。

建立一個類來提供 ORM

我們建立檔案 tabledef.py。在這個檔案中,我們將定義一個類 Student。下面類的抽象視覺化:

Student
+ username: String+ firstname: String+ lastname: String+ university: String

應該能注意到我們沒有定義任何方法,只定義類的變數。這是因為我們將此類對映到資料庫,因此不需要任何方法。

這是 tabledef.py 的內容:

from sqlalchemy import *
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy import Column, Date, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref
 
engine = create_engine('sqlite:///student.db', echo=True)
Base = declarative_base()
 
########################################################################
class Student(Base):
    """"""
    __tablename__ = "student"
 
    id = Column(Integer, primary_key=True)
    username = Column(String)
    firstname = Column(String)
    lastname = Column(String)
    university = Column(String)
 
    #----------------------------------------------------------------------
    def __init__(self, username, firstname, lastname, university):
        """"""
        self.username = username
        self.firstname = firstname
        self.lastname = lastname
        self.university = university
 Base.metadata.create_all(engine)

執行:

python tabledef.py

ORM 建立了資料庫檔案 tabledef.py。它會將 SQL 查詢輸出到螢幕,在我們的例子中它顯示:

CREATE TABLE student (
    id INTEGER NOT NULL, 
    username VARCHAR, 
    firstname VARCHAR, 
    lastname VARCHAR, 
    university VARCHAR, 
    PRIMARY KEY (id)
)

因此,當我們定義一個類時,ORM 為我們建立了資料庫表。這張表還是空的。

將資料插入資料庫

資料庫表仍為空。我們可以使用 Python 物件將資料插入資料庫。因為我們使用 SqlAlchemy ORM,所以我們不必編寫單個 SQL 查詢。我們現在只需建立我們提供給 ORM 的 Python 物件。將下面的程式碼儲存為 dummy.py

import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from tabledef import *
 
engine = create_engine('sqlite:///student.db', echo=True)
 Session = sessionmaker(bind=engine)
session = Session()
 user = Student("james","James","Boogie","MIT")
session.add(user)
 
user = Student("lara","Lara","Miami","UU")
session.add(user)
 
user = Student("eric","Eric","York","Stanford")
session.add(user)
 session.commit()

執行:

python dummy.py

ORM 將 Python 物件對映到關聯式資料庫。這意味著你沒有與應用程式進行任何直接互動,只需與物件進行互動即可。如果使用 SQLiteman 或 SQLite 資料庫應用程式開啟資料庫,你將發現該表已建立:

id username firstname lastname university
1 1 james James Boogie MIT
2 2 lara Lara Miami UU
3 3 eric Eric York Stanford

查詢資料

我們可以使用下面的程式碼查詢表的所有專案。請注意,Python 會將每條記錄視為 Students 類定義的唯一物件。將程式碼儲存為 demo.py

import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from tabledef import *
 
engine = create_engine('sqlite:///student.db', echo=True)
 Session = sessionmaker(bind=engine)
session = Session()
 for student in session.query(Student).order_by(Student.id):
    print student.firstname, student.lastname

執行時你會看到:

James Boogie
Lara Miami
Eric York

要選擇單個物件,請使用 filter() 方法。下面來演示:

import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from tabledef import *
 
engine = create_engine('sqlite:///student.db', echo=True)
 Session = sessionmaker(bind=engine)
session = Session()
 for student in session.query(Student).filter(Student.firstname == 'Eric'):
    print student.firstname, student.lastname

輸出:

Eric York

最後,如果你不希望 ORM 輸出任何 SQL 查詢,請將 create_engine 語句更改為:

engine = create_engine('sqlite:///student.db', echo=False)