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编程语言的35个与众不同之处(语言特征和使用技巧)
Jul 07 Python
闭包在python中的应用之translate和maketrans用法详解
Aug 27 Python
纯Python开发的nosql数据库CodernityDB介绍和使用实例
Oct 23 Python
PYTHON压平嵌套列表的简单实现
Jun 08 Python
Python中对象的引用与复制代码示例
Dec 04 Python
python中字符串的操作方法大全
Jun 03 Python
解决python测试opencv时imread导致的错误问题
Jan 26 Python
详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本
Feb 25 Python
PyQt QListWidget修改列表项item的行高方法
Jun 20 Python
使用虚拟环境打包python为exe 文件的方法
Aug 29 Python
Pytorch 中retain_graph的用法详解
Jan 07 Python
Python获取android设备cpu和内存占用情况
Nov 15 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
MySQL数据源表结构图示
2008/06/05 PHP
PHP chmod 函数与批量修改文件目录权限
2010/05/10 PHP
关于PHP session 存储方式的详细介绍
2013/06/25 PHP
php使用array_rand()函数从数组中随机选择一个或多个元素
2014/04/28 PHP
php实现通用的信用卡验证类
2015/03/24 PHP
PHP读取文件,解决中文乱码UTF-8的方法分析
2020/01/22 PHP
editable.js 基于jquery的表格的编辑插件
2011/10/24 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
2014/02/19 Javascript
js 通过cookie实现刷新不变化树形菜单
2014/10/30 Javascript
JavaScript获得页面base标签中url的方法
2015/04/03 Javascript
简介可以自动完成UI的AngularJS工具angular-smarty
2015/06/23 Javascript
新手快速学习JavaScript免费教程资源汇总
2015/06/25 Javascript
微信小程序之ES6与事项助手的功能实现
2016/11/30 Javascript
jQuery分页插件jquery.pagination.js使用方法解析
2017/02/09 Javascript
Bootstrap选项卡学习笔记分享
2017/02/13 Javascript
VUE元素的隐藏和显示(v-show指令)
2017/06/23 Javascript
详解webpack打包nodejs项目(前端代码)
2018/09/19 NodeJs
javascript中toFixed()四舍五入使用方法详解
2018/09/28 Javascript
js变量值传到php过程详解 将php解析成数据
2019/06/26 Javascript
微信公众号服务器验证Token步骤图解
2019/12/30 Javascript
详解微信小程序轨迹回放实现及遇到的坑
2021/02/02 Javascript
解决Python字典写入文件出行首行有空格的问题
2017/09/27 Python
python中设置超时跳过,超时退出的方式
2019/12/13 Python
Python递归函数特点及原理解析
2020/03/04 Python
vscode写python时的代码错误提醒和自动格式化的方法
2020/05/07 Python
matplotlib更改窗口图标的方法示例
2021/02/03 Python
马来西亚在线时尚女装商店:KEI MAG
2017/09/28 全球购物
意大利婴儿产品网上商店:Mukako
2018/10/14 全球购物
C#笔试题集合
2013/06/21 面试题
幼儿园元旦亲子活动方案
2014/02/17 职场文书
我为党旗添光彩演讲稿
2014/09/10 职场文书
幼儿园五一劳动节活动总结
2015/02/09 职场文书
2015年采购工作总结
2015/04/10 职场文书
2015年司法所工作总结
2015/04/27 职场文书
导游词之天津盘山
2019/11/01 职场文书
python中filter,map,reduce的作用
2022/06/10 Python