Python的SQLAlchemy框架使用入门


Posted in Python onApril 29, 2015

数据库表是一个二维表,包含多行多列。把一个表的内容用Python的数据结构表示出来的话,可以用一个list表示多行,list的每一个元素是tuple,表示一行记录,比如,包含id和name的user表:

[
  ('1', 'Michael'),
  ('2', 'Bob'),
  ('3', 'Adam')
]

Python的DB-API返回的数据结构就是像上面这样表示的。

但是用tuple表示一行很难看出表的结构。如果把一个tuple用class实例来表示,就可以更容易地看出表的结构来:

class User(object):
  def __init__(self, id, name):
    self.id = id
    self.name = name

[
  User('1', 'Michael'),
  User('2', 'Bob'),
  User('3', 'Adam')
]

这就是传说中的ORM技术:Object-Relational Mapping,把关系数据库的表结构映射到对象上。是不是很简单?

但是由谁来做这个转换呢?所以ORM框架应运而生。

在Python中,最有名的ORM框架是SQLAlchemy。我们来看看SQLAlchemy的用法。

首先通过easy_install或者pip安装SQLAlchemy:

$ easy_install sqlalchemy

然后,利用上次我们在MySQL的test数据库中创建的user表,用SQLAlchemy来试试:

第一步,导入SQLAlchemy,并初始化DBSession:

# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建对象的基类:
Base = declarative_base()

# 定义User对象:
class User(Base):
  # 表的名字:
  __tablename__ = 'user'

  # 表的结构:
  id = Column(String(20), primary_key=True)
  name = Column(String(20))

# 初始化数据库连接:
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)

以上代码完成SQLAlchemy的初始化和具体每个表的class定义。如果有多个表,就继续定义其他class,例如School:

class School(Base):
  __tablename__ = 'school'
  id = ...
  name = ...

create_engine()用来初始化数据库连接。SQLAlchemy用一个字符串表示连接信息:

'数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'

你只需要根据需要替换掉用户名、口令等信息即可。

下面,我们看看如何向数据库表中添加一行记录。

由于有了ORM,我们向数据库表中添加一行记录,可以视为添加一个User对象:

# 创建session对象:
session = DBSession()
# 创建新User对象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()

可见,关键是获取session,然后把对象添加到session,最后提交并关闭。Session对象可视为当前数据库连接。

如何从数据库表中查询数据呢?有了ORM,查询出来的可以不再是tuple,而是User对象。SQLAlchemy提供的查询接口如下:

# 创建Session:
session = DBSession()
# 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
user = session.query(User).filter(User.id=='5').one()
# 打印类型和对象的name属性:
print 'type:', type(user)
print 'name:', user.name
# 关闭Session:
session.close()

运行结果如下:

type: <class '__main__.User'>
name: Bob

可见,ORM就是把数据库表的行与相应的对象建立关联,互相转换。

由于关系数据库的多个表还可以用外键实现一对多、多对多等关联,相应地,ORM框架也可以提供两个对象之间的一对多、多对多等功能。

例如,如果一个User拥有多个Book,就可以定义一对多关系如下:

class User(Base):
  __tablename__ = 'user'

  id = Column(String(20), primary_key=True)
  name = Column(String(20))
  # 一对多:
  books = relationship('Book')

class Book(Base):
  __tablename__ = 'book'

  id = Column(String(20), primary_key=True)
  name = Column(String(20))
  # “多”的一方的book表是通过外键关联到user表的:
  user_id = Column(String(20), ForeignKey('user.id'))

当我们查询一个User对象时,该对象的books属性将返回一个包含若干个Book对象的list。
小结

ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。

正确使用ORM的前提是了解关系数据库的原理。

Python 相关文章推荐
python用模块zlib压缩与解压字符串和文件的方法
Dec 16 Python
Flask数据库迁移简单介绍
Oct 24 Python
python使用opencv按一定间隔截取视频帧
Mar 06 Python
使用Flask集成bootstrap的方法
Jul 24 Python
django 多对多表的创建和插入代码实现
Sep 09 Python
win10系统下python3安装及pip换源和使用教程
Jan 06 Python
Python模块future用法原理详解
Jan 20 Python
详解python中groupby函数通俗易懂
May 14 Python
Python使用configparser读取ini配置文件
May 25 Python
Python爬虫爬取博客实现可视化过程解析
Jun 29 Python
pytorch加载自己的图像数据集实例
Jul 07 Python
pycharm配置QtDesigner的超详细方法
Jan 25 Python
python使用post提交数据到远程url的方法
Apr 29 #Python
python实现根据ip地址反向查找主机名称的方法
Apr 29 #Python
连接Python程序与MySQL的教程
Apr 29 #Python
python实现通过代理服务器访问远程url的方法
Apr 29 #Python
python实现带错误处理功能的远程文件读取方法
Apr 29 #Python
python使用socket远程连接错误处理方法
Apr 29 #Python
python使用socket连接远程服务器的方法
Apr 29 #Python
You might like
德劲1107的电路分析与打磨
2021/03/02 无线电
Fine Uploader文件上传组件应用介绍
2013/01/06 PHP
ThinkPHP文件上传实例教程
2014/08/22 PHP
php实现压缩多个CSS与JS文件的方法
2014/11/11 PHP
php的crc32函数使用时需要注意的问题(不然就是坑)
2015/04/21 PHP
JS(jQuery)实现聊天接收到消息语言自动提醒功能详解【提示“您有新的消息请注意查收”】
2019/04/16 PHP
jquery checkbox,radio是否选中的判断代码
2010/03/20 Javascript
ExtJS PropertyGrid中使用Combobox选择值问题
2010/06/13 Javascript
教你如何在 Javascript 文件里使用 .Net MVC Razor 语法
2014/07/23 Javascript
JS实现动态给图片添加边框的方法
2015/04/01 Javascript
Angularjs整合微信UI(weui)
2016/03/15 Javascript
简单学习vue指令directive
2016/11/03 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
2017/02/08 Javascript
jQuery插件HighCharts实现的2D回归直线散点效果示例【附demo源码下载】
2017/03/09 Javascript
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
JS实现的JSON序列化操作简单示例
2018/07/02 Javascript
LayerClose弹窗关闭刷新方法
2018/08/17 Javascript
JS实现马赛克图片效果完整示例
2019/04/13 Javascript
JS大坑之19位数的Number型精度丢失问题详解
2019/04/22 Javascript
实例解析Python的Twisted框架中Deferred对象的用法
2016/05/25 Python
简单了解什么是神经网络
2017/12/23 Python
用python做游戏的细节详解
2019/06/25 Python
python中如何使用虚拟环境
2020/10/14 Python
python 邮件检测工具mmpi的使用
2021/01/04 Python
python urllib和urllib3知识点总结
2021/02/08 Python
美国知名日用品连锁超市:Dollar General(多来店)
2017/01/14 全球购物
MATCHESFASHION.COM美国官网:英国奢侈品零售商
2018/10/29 全球购物
沙特阿拉伯排名第一的在线时尚购物应用程序:1Zillion
2020/08/08 全球购物
银行批评与自我批评
2014/02/10 职场文书
简单的大学生自我鉴定
2014/02/18 职场文书
师范教师专业大学生职业生涯规划范文
2014/03/02 职场文书
2014班子“三严三实”对照检查材料思想汇报
2014/09/18 职场文书
地下停车场租赁协议范本
2014/10/07 职场文书
商标侵权律师函
2015/05/27 职场文书
导游词之太湖
2019/10/08 职场文书
Python 全局空间和局部空间
2022/04/06 Python