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格式化css文件的方法
Mar 10 Python
Python工程师面试题 与Python基础语法相关
Jan 14 Python
Python django实现简单的邮件系统发送邮件功能
Jul 14 Python
使用Django和Python创建Json response的方法
Mar 26 Python
python使用matplotlib模块绘制多条折线图、散点图
Apr 26 Python
使用pyecharts生成Echarts网页的实例
Aug 12 Python
利用Python实现kNN算法的代码
Aug 16 Python
python3 实现爬取TOP500的音乐信息并存储到mongoDB数据库中
Aug 24 Python
基于django micro搭建网站实现加水印功能
May 22 Python
查看keras各种网络结构各层的名字方式
Jun 11 Python
Python实现王者荣耀自动刷金币的完整步骤
Jan 22 Python
python游戏开发Pygame框架
Apr 22 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
PHP+APACHE实现用户论证的方法
2006/10/09 PHP
PHP文件下载实例代码浅析
2016/08/17 PHP
JQuery 无废话系列教程(二) jquery实战篇上
2009/06/23 Javascript
js全屏显示显示代码的三种方法
2013/11/11 Javascript
JavaScript位置与大小(1)之正确理解和运用与尺寸大小相关的DOM属性
2015/12/26 Javascript
Bootstrap按钮下拉菜单组件详解
2016/05/10 Javascript
Bootstrap实现的经典栅格布局效果实例【附demo源码】
2017/03/30 Javascript
Angular4学习笔记之准备和环境搭建项目
2017/08/01 Javascript
javascript 取小数点后几位几种方法总结
2017/08/02 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
快速处理vue渲染前的显示问题
2018/03/05 Javascript
Vue 中axios配置实例详解
2018/07/27 Javascript
在vue中v-bind使用三目运算符绑定class的实例
2018/09/29 Javascript
JS使用Prim算法和Kruskal算法实现最小生成树
2019/01/17 Javascript
微信小程序云开发修改云数据库中的数据方法
2019/05/18 Javascript
构建大型 Vue.js 项目的10条建议(小结)
2019/11/14 Javascript
Vue两个版本的区别和使用方法(更深层次了解)
2020/02/16 Javascript
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
Element Notification通知的实现示例
2020/07/27 Javascript
Python中lambda的用法及其与def的区别解析
2014/07/28 Python
python实现颜色rgb和hex相互转换的函数
2015/03/19 Python
用python求一个数组的和与平均值的实现方法
2019/06/29 Python
tensorflow 查看梯度方式
2020/02/04 Python
Idea安装python显示无SDK问题解决方案
2020/08/12 Python
HTML5 3D衣服摇摆动画特效
2016/03/17 HTML / CSS
BLACKMORES澳洲官网:澳大利亚排名第一的保健品牌
2018/09/27 全球购物
美国椅子和沙发制造商:La-Z-Boy
2020/10/25 全球购物
专升本自我鉴定
2013/10/10 职场文书
函授大专自我鉴定
2013/11/01 职场文书
党校学习思想汇报
2014/01/06 职场文书
放飞蜻蜓反思
2014/02/05 职场文书
《可爱的动物》教学反思
2014/02/22 职场文书
纪念九一八事变83周年国旗下讲话稿
2014/09/15 职场文书
个人自查自纠材料
2014/10/14 职场文书
干部作风建设年活动剖析材料
2014/10/23 职场文书
党的群众路线教育实践活动领导班子整改方案
2014/10/25 职场文书