Python数据库ORM SQLAlchemy 0.7学习笔记(2) 定义映射
2015-08-27 14:53
489 查看
!本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使用方面,本人不保证相应的兼容和可操作性。
昨天简单介绍了SQLAlchemy的使用,但是没有能够涉及其最精彩的ORM部分,今天我将简单说明一下,当然主要还是讲解官方文档的内容,由于是学习笔记,有可能存在精简或者自己理解的部分,不做权威依据。
当我们开始使用ORM,一种可配置的结构可以用于描述我们的数据库表,稍后我们定义的类将会被映射到这些表上。当然现代的SQLAlchemy(新版本SQLAlchemy,原文是modern SQLAlchemy)使用Declarative把这两件事一起做了,即允许我们把创建类和描述定义数据库表以及它们之间的映射关系一次搞定。
这段话是什么意思呢?简单来说吧,SQLAlchemy分为Classic (经典模式)和Modern (现代模式),Classic定义数据库表的模式比较传统,需要先描述这个表。
1. Classic 映射
比如以官方文档中的例子,我们拥有表结构如下:
下面我们描述这张表:
好,这样我们的表算是描述完成了,接下来我们需要定义我们的Python类,比如这样的:
如何让我们定义的类与之前描述的表结构发生映射关系就是我们接下来要做的:
大家注意到mapper函数,第一个参数是我们类的名称,第二个参数是我们先前描述的表定义。
这就是传统的定义ORM的方法,有关这个方法的更多信息,可以阅读文档Mapper Configuration,以后有机会再和大家详谈。
2. Modern 映射
当大家都乐此不疲的定义描述表,定义类,再映射来实现ORM的时候,SQLAlchemy团队搞出了更简单的映射方法,那就是Modern模式了,即通过定义映射类来一次性完成所有任务。
为了定义的类能够被SQLAlchemy管理,所以引入了Declarative这个概念,也就是说我们所有的类必须是Declarative基类的子类,而这个基类可以通过下面的办法来获取:
当然一个程序内,这个基类最好是唯一的,建议存储在全局变量比如Base中供所有映射类使用。
现在通过刚才的代码我们得到了名为Base的基类,通过这个基类我们可以定义N多的映射子类,而这些子类都能被SQLAlchemy Declarative系统管理到。
下面我们还是看刚才的那个users表的例子:
就这段代码就完成了我们先前在Classic中需要的三步,代码比原先更简洁和容易管理了,同刚才Classic中Table定义的Column,这个代表数据库表中的列,当然Integer和String代表着数据库表的字段类型了。
这样User类就建立起与数据库表的映射,真实表的名字可以使用
大家可能注意到User类中还包含有通常意义上的Python魔术方法,包含
当然User类唯一不能马虎的就是必须继承至Base,这个Base就是刚才我们通过
Declarative系统管理并操作这些映射类和数据库表。
实际上包括继承的Base类,所有的类都应该是Python的新式类(new style class),关于新式类的更多信息可以参考Python手册。
随着我们的User映射类通过Declarative系统构造成功,我们就拥有了相关的定义信息,比如在Classic定义中介绍的
当然找到描述表的数据结构,也应该能找到mapper,我们的Mapper对象可以通过
同样的MetaData可以通过
好啦,下面轻松一下,见证奇迹的时刻,我们需不需要定义创建好实体数据库然后再定义ORM?对于SQLAlchemy来说这些都是小事一桩,其都可以给你一手包办,也就是说你可以完全不必理会数据库,交给SQLAlchemy就可以了,比如通过
由于我们开启了engine的
这样简单的
时间不早了,今天先聊到这儿,下次再谈SQLAlchemy的其他特性。
昨天简单介绍了SQLAlchemy的使用,但是没有能够涉及其最精彩的ORM部分,今天我将简单说明一下,当然主要还是讲解官方文档的内容,由于是学习笔记,有可能存在精简或者自己理解的部分,不做权威依据。
当我们开始使用ORM,一种可配置的结构可以用于描述我们的数据库表,稍后我们定义的类将会被映射到这些表上。当然现代的SQLAlchemy(新版本SQLAlchemy,原文是modern SQLAlchemy)使用Declarative把这两件事一起做了,即允许我们把创建类和描述定义数据库表以及它们之间的映射关系一次搞定。
这段话是什么意思呢?简单来说吧,SQLAlchemy分为Classic (经典模式)和Modern (现代模式),Classic定义数据库表的模式比较传统,需要先描述这个表。
1. Classic 映射
比如以官方文档中的例子,我们拥有表结构如下:
CREATE TABLE [users] ( [id] INTEGER PRIMARY KEY, [name] TEXT NOT NULL, [fullname] TEXT NOT NULL, [password] TEXT NOT NULL ); |
from sqlalchemy import Table, MetaData, Column, Integer, String metadata = MetaData() user = Table('users', metadata, Column('id', Integer, primary_key=True), Column('name', String(50)), Column('fullname', String(50)), Column('password', String(12)) ) |
class User(object): def __init__(self, name, fullname, password): self.name = name self.fullname = fullname self.password = password |
from sqlalchemy.orm import mapper mapper(User, user) |
这就是传统的定义ORM的方法,有关这个方法的更多信息,可以阅读文档Mapper Configuration,以后有机会再和大家详谈。
2. Modern 映射
当大家都乐此不疲的定义描述表,定义类,再映射来实现ORM的时候,SQLAlchemy团队搞出了更简单的映射方法,那就是Modern模式了,即通过定义映射类来一次性完成所有任务。
为了定义的类能够被SQLAlchemy管理,所以引入了Declarative这个概念,也就是说我们所有的类必须是Declarative基类的子类,而这个基类可以通过下面的办法来获取:
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() |
现在通过刚才的代码我们得到了名为Base的基类,通过这个基类我们可以定义N多的映射子类,而这些子类都能被SQLAlchemy Declarative系统管理到。
下面我们还是看刚才的那个users表的例子:
from sqlalchemy import Column, Integer, String class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) fullname = Column(String) password = Column(String) def __init__(self, name, fullname, password): self.name = name self.fullname = fullname self.password = password def __repr__(self): return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password) |
这样User类就建立起与数据库表的映射,真实表的名字可以使用
__tablename__指明,然后是表列的集合,包括
id、
name、
fullname以及
password,当然想必大家已经知道了,我们通过
primary_key=True已经指明
id为主键了。当然一些数据库表可能不包含有主键(例如视图View,当然视图也可以被映射),ORM为了能够实际映射表需要至少一个列被定义为主键列。多列,比如复合多主键也能够被很好地映射支持。
大家可能注意到User类中还包含有通常意义上的Python魔术方法,包含
__init__()初始化类(构造方法)以及
__repr__()字符串化支持方法,当然这些都是可选的,如果需要这个类可以加入程序所需要的任意多方法或者属性,你只要把这个类看作一个普通的Python类就可以了。
当然User类唯一不能马虎的就是必须继承至Base,这个Base就是刚才我们通过
declarative_base()生成的类,通过它我们可以接下来让SQLAlchemy
Declarative系统管理并操作这些映射类和数据库表。
实际上包括继承的Base类,所有的类都应该是Python的新式类(new style class),关于新式类的更多信息可以参考Python手册。
随着我们的User映射类通过Declarative系统构造成功,我们就拥有了相关的定义信息,比如在Classic定义中介绍的
Table()描述,也包含映射到表的类,就是User自身,我们可以通过
User.__table__来查看我们的表描述情况:
>>> User.__table__ Table('users', MetaData(None), Column('id', Integer(), table=<users>, primary_key=True, nullable=False), Column('name', String(), table=<users>), Column('fullname', String(), table=<users>), Column('password', String(), table=<users>), schema=None) |
__mapper__属性来获取,比如这样的:
>>> User.__mapper__ <Mapper at 0x...; User> |
.metadata属性找到。
好啦,下面轻松一下,见证奇迹的时刻,我们需不需要定义创建好实体数据库然后再定义ORM?对于SQLAlchemy来说这些都是小事一桩,其都可以给你一手包办,也就是说你可以完全不必理会数据库,交给SQLAlchemy就可以了,比如通过
MetaData.create_all()并将engine参数传入即可(什么是engine?参考我的笔记1),比如通过下面的方式创建我们的users表。
>>> Base.metadata.create_all(engine) PRAGMA table_info("users") () CREATE TABLE users ( id INTEGER NOT NULL, name VARCHAR, fullname VARCHAR, password VARCHAR, PRIMARY KEY (id) ) () COMMIT |
echo=True,所以在交互命令下SQLAlchemy把SQL语句也输出了,正好可以检验是否符合我们的要求。
这样简单的
create_all()我们就轻松建立起先前ORM映射定义的表啦。
时间不早了,今天先聊到这儿,下次再谈SQLAlchemy的其他特性。
相关文章推荐
- Python数据库ORM SQLAlchemy 0.7学习笔记(1) 概要
- 循环下载图片,跳过不可用url
- 使用py2exe 将python文件转成exe文件(以及 error: [Errno 2] No such file or directory: 'MSVCP90.dll'解决方法)
- Python扩展包安装方法以及Python添加库(模块)
- python的学习库资料
- Python & Deep Belief Network
- python学习笔记:easygui的简单示例
- 调用python 报R6034 错误
- python学习--核心编程5习题以及知识点记录
- Python 3.4 简单的抓图脚本
- Python 2.7 (64 bit )下安装 OpenCV 3.0
- python setuptools安装与psutil模块测试
- python文件中的__name__=='__main__'的使用及调用其他py文件中的函数方法
- multiprocessing 基于进程的“线程式”接口 python
- python setuptools安装与psutil模块测试
- 两个使用Python脚本操作文件的小示例分享
- python 读写Json的中文编码问题
- IDEA中python内建函数出现红色波浪下划线,但运行正常
- 关于Python中,re.sub(pattern, repl, string, count=0, flags=0)方法的个人理解
- Python中的map(function,iterable, ...)方法