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)