来源:本文章摘抄于《知了课堂》,本人也是知了课堂的学生
相关
Python-SQLAlchemy介绍和基本使用
Python-SQLAlchemy(1)
Python-SQLAlchemy(2)
Python-SQLAlchemy(3)
Python-SQLAlchemy(4)
Python-SQLAlchemy(5)
使用SQLAlchemy:
要使用 ORM 来操作数据库,首先需要创建一个类来与对应的表进行映射。现在以 User 表来作为例子,它有自增长的 id
, name
,fullname
,password
这些字段,那么对应的类为:
from sqlalchemy import Column, Integer, String
from constants import DB_URI # 数据库配置
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine(DB_URI, echo=True)
# 所有的类都要继承自 `declarative_base`
Base = declarative_base(engine)
class User(Base):
# 定义表名为 users
__tablename__ = 'users'
# 将 id 设置为主键,并且默认是自增长的
id = Column(Integer, primary_key=True)
name = Column(String(50))
fullname = Column(String(50))
password = Column(String(100))
# 打印
def __repr__(self):
return "<User(id=%s, name=%s, fullname=%s)>"%(self.id, self.name, self.fullname)
SQLAlchemy 会自动的设置第一个 Integer
的主键并且没有被标记为外键的字段添加自增长的属性。因此 id 自动变成自增长的。以上创建完表的映射类之后,还没有真正映射到数据库中,执行一下代码将类映射到数据库中:
Base.metadata.create_all()
接下来添加数据:
ed_user = User(name='ed', fullname='Ed Jones', password='123456')
# 打印
print ed_user.name
> ed
print ed_user.fullname
> Ed Jones
print ed_user.id
> None
可以看到, name
和 password
都能正常打印,唯独 id
为 None
,这是因为 id
是个自增长的主键,还未插入数据库中,id
是不存在的。接下来我们把数据插入数据库中。
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
# 或者
# Session = sessionmaker()
# Session.configure(bind=engine)
session = Session()
ed_user = User(name='ed', fullname='Ed Jones', password='123456')
session.add(ed_user)
现在只是吧数据添加到 session
中,但是并没有真正的把数据储存到数据库中。如果需要把数据存储到数据库中,还要做一次 commit
操作:
session.commit()
print ed_user.id
> 1
这个时候 ed_user
就已经有 id
。说明已经插入到数据库中。有人肯定有疑问,为什么添加到 session
中之后还要做一次 commit
操作呢,这是因为,在 SQLAlchemy
的 ORM
实现中,在做 commit
操作之前,所有的操作都是在事务中进行的,因此如果你要将事务中的操作真正的映射到数据库中,就需要 commit
操作。既然用到了事务,这里就要提一下回滚操作了。看下面代码如何展示回滚操作:
# 修改 ed_user 的用户名
ed_user.name = 'Edwardo'
# 创建一个新的用户
fake_user = User(name='fakeuser', fullname='Invalid', password='123456')
# 将新创建的fake_user 添加到 session 中
session.add(fake_user)
# 判断 `fake_user` 是否在 `session` 中存在
print fake_user in session
> True
# 从数据库中查找 name = Edwardo 的用户
tmp_user = session.query(User).filter_by(name='Edwardo')
# 打印 tmp_user 的 name
print tmp_user
# 打印出查找到的 tmp_user 对象,注意这个对象的 name 属性已经在事务中被修改为 Edwardo了
> <User(name=Edwardo, fullname=Ed Jones, password=123456)>
# 刚刚所有的操作都是在事务中进行的,现在做回滚操作
session.rollback()
# 再打印tmp_user
print tmp_user
> <User(name=ed, fullname=Ed Jones, password=123456)>
# 再看 fake_user 是否在 session 中
print fake_user in session
> False
接下来看如何进行查找操作,查找操作是通过 session.query()
方法实现的,这个方法会返回一个 Query
对象,Query
对象相当于一个数组,装载了查找出来的数据,并且可以进行迭代。具体里面装的什么数据,就要看向 session.query()
方法传的什么参数了,如果只是传一个 ORM
的类名作为参数,那么提取出来的数据就是这里类的实例了,比如:
for instance in session.query(User).order_by(User.id):
print instance
# 输出所有的 user 实例
><User(id=2, name='ed', fullname='Ed Jones', password='123456')>
><User(id=3, name='be', fullname='be Engine', password='123456')>
#如果传递了两个及两个以上的对象,或者是传递的是 `ORM` 类的属性,那么查找出来的就是元组:
for instance in session.query(User.name):
print instance
# 输出所有的查找结果
>('ed', )
>('be', )
# 或者:
for instance in session.query(User, User.name).all()
print instance
# 输出
>(<User(id=2, name=ed, fullname=ed Jones, password=123456)>, 'ed')
>(<User(id=3, name=be, fullname=Be Engine, password=123456)>, 'be')
#另外,还可以对查找的结果进行切边操作:
for instance in session.query(User).order_by(User.id)[1:3]
print instance
如果想对结果进行过滤,可以使用 filter_by
和 filter
两个方法,这两个方法都是用来做过滤的,区别在于,filter_by
是传入关键字的参数,filter
是传入条件判断,并且 filter
能够传入的条件更加灵活,请看例子:
# 第一种:使用 filter_by 过滤
for name in session.query(User.name).filter_by(fullname='Ed Jones'):
print name
> ('Ed',)
# 第二种: 使用 filter 过滤
for name in session.query(User.name).filter(User.fullname=='Ed Jones'):
print name
> ('Ed', )
网友评论