sqlalchemy操作手册

orm操作是所有完整软件中后端处理最重要的一部分,主要完成了后端程序和数据库之间的数据同步和持久化的操作,本文基于sqlalchemy官方文档进行整理,完成sqlalchemy的核心操作

目录

什么是ORM 

常见的ORM操作流程和步骤 

sqlalchemy基础操作 

1 什么是ORM 

2 常见的ORM操作流程和步骤 

3 sqlalchemy基础操作 

3.1. 安装 3

3.2. 连接引擎 3

3.3. 连接会话 4

3.4. ORM之Object操作 4

3.4.1. 基础类 4

3.4.2. 数据类型创建 5

3.4.3. 数据类型映射操作 5

3.5. 增加和更新 6

3.6. 查询对象Query 6

3.6.1. 常规查询query 6

3.6.2. 指定排序查询 6

3.6.3. 指定列查询 7

3.6.4. 指定列属性别名 7

3.6.5. 指定类型别名 7

3.6.6. 切片查询 7

3.7. 条件筛选filter 7

3.7.1. 等值条件——equals / not equals 8

3.7.2. 模糊条件——like 8

3.7.3. 范围条件——in / not in 8

3.7.4. 空值条件——is null / is not null 8

3.7.5. 并且条件——AND 8

3.7.6. 或者条件——OR 9

3.7.7. SQL语句查询 9

3.8. 查询结果 9

3.8.1. all()函数返回查询列表 9

3.8.2. filter()函数返回单项数据的列表生成器 9

3.8.3. one()/one_or_none()/scalar()返回单独的一个数据对象 9

1. 什么是ORM

ORM:Object Relation Mapping,最初主要描述的是程序中的Object对象和关系型数据库中Rlation关系(表)之间的映射关系,目前来说也是描述程序中对象和数据库中数据记录之间的映射关系的统称,是一种进行程序和数据库之间数据持久化的一种编程思想。

2. 常见的ORM操作流程和步骤

常规情况下,软件程序中的ORM操作主要有四个操作场景:增、删、改、查

核心操作一般会区分为:增删改、查询

增删改操作

增加操作:程序中存在的一个对象Object数据,通过[ORM]核心模块进行增加的函数定义将对象保存到数据库的操作过程;如~注册操作中,通过用户输入的账号密码等信息创建了一个独立的对象,通过add()函数将对象增加保存到数据库中,数据库中就存在用户这个对象数据了。

修改操作:程序中存在的一个对象Object数据,有自己的id编号(可以是程序中自行赋值定义、更多的操作是从数据库中查询出来存在的一个对象),通过[ORM]核心模块进行修改函数的定义将对象改变的数据更新到数据库中已经存在的记录中的过程;如~用户更改登录密码操作时,根据程序中查询得到的一个用户[id编号、账号、密码、..],在程序中通过改变其密码属性数据,然后通过update()函数将改变的数据更新保存到数据库中,数据库中原来的数据就发生了新的改变。

删除操作:程序中存在的一个对象或者已知的id编号,通过主键编号或者对象的任意属性进行数据库中数据记录的删除的操作过程;如~管理员删除某个会员账号的操作,通过获取要删除会员的账号,然后通过delete()函数将要删除的会员信息告知数据库执行删除操作,数据库中的某条存在的数据记录就被删除掉了。

3. sqlalchemy基础操作

ORM操作在实际项目中的应用非常多,涉及到的框架也是根据不同的项目有不同的处理模块,不过操作流程和步骤都是大同小异基本没有什么太大变化,唯一需要注意的就是在实际操作过程中你要使用的ORM框架的处理性能和是否支持事务、是否支持分布式等特性来进行确定使用哪个ORM框架进行操作,一般在python程序中ORM操作都是对mysqldb和pymysql这样的底层模块进行的封装处理。例如文章中要讲解的sqlalchemy就是底层封装mysqldb的实现,不过我们的在使用过程中需要使用pymysql进行替代。

3.1. 安装

首先确保你的PC已经具备了完善的python开发环境

安装sqlalchemy,执行如下命令使用pip安装即可

$ pip install sqlalchemy

或者执行如下命令通过easy_install进行安装

$ easy_install sqlalchemy

安装完成之后,可以通过引入sqlalchemy进行版本查看,确认sqlalchemy安装成功

>>> import sqlalchemy>>> sqlalchemy.__version__'1.2.0b3'

3.2. 连接引擎

使用sqlalchemy进行数据库操作,首先我们需要建立一个指定数据库的连接引擎对象

建立引擎对象的方式被封装在了sqlalchemy.create_engine函数中,通过指定的数据库连接信息就可以进行创建

创建数据库连接引擎时参数设置语法:

dialect[+driver]://user:password@host/dbname[?key=value..]# 引入建立引擎的模块from sqlalchemy import create_engine# 创建一个和mysql数据库之间的连接引擎对象engine = create_engine("mysql://root:root@localhost/py1709",

encoding="utf-8", echo=True)

指定的数据库连接字符串表示了目标数据库的配置信息;encoding配置参数指定了和和数据库之间交换的数据的编码方式,同时echo参数表示随时在控制台展示和数据库之间交互的各种信息

create_engine()函数返回的是sqlalchemy最核心的接口之一,该引擎对象会根据开发人员指定的数据库进行对应的sql api的调用处理

连接postgresql数据库:

engine = create_engine("postgresql://scott:tiger@localhost/test")

连接mysql数据库:

engine = create_engine("mysql://scott:tiger@hostname/dbname",

encoding='utf-8', echo=True)

其他连接方式请参考官方文档:http://docs.sqlalchemy.org/en/latest/

3.3. 连接会话

创建了数据库连接引擎对象之后,我们需要获取和指定数据库之间的连接,通过连接进行数据库中数据的增删改查操作,和数据库的连接我们称之为和指定数据库之间的会话,通过指定的一个模块

sqlalchemy.sessionmaker进行创建# 引入创建session连接会话需要的处理模块from sqlalchemy.orm import sessionmaker# 创建一个连接会话对象;需要指定是和那个数据库引擎之间的会话Session = sessionmaker(bind=engine)session = Session()# 接下来~就可以用过session会话进行数据库的数据操作了。

PS:如果在创建会话的时候还没有指定数据库引擎,可以通过如下的方式完成会话操作

Session = sessionmaker()..Session.configure(bind=engine)session = Session()..

3.4. ORM之Object操作

我们的程序中的对象要使用sqlalchemy的管理,实现对象的orm操作,就需要按照框架指定的方式进行类型的创建操作,sqlalchemy封装了基础类的声明操作和字段属性的定义限制方式,开发人员要做的事情就是引入需要的模块并在创建对象的时候使用它们即可

基础类封装在sqlalchemy.ext.declarative.declarative_base模块中

字段属性的定义封装在sqlalchemy模块中,通过sqlalchemy.Column定义属性,通过封装的Integer、String、Float等定义属性的限制

3.4.1. 基础类

创建基础类的方式如下:

# 引入需要的模块from sqlalchemy.ext.declarative import declarative_base# 创建基础类BaseModel = declarative_base()

3.4.2. 数据类型创建

创建数据模型的操作

# 引入需要的模块from sqlalchemy import Column, String, Integer# 创建用户类型class User(BaseModel):    # 定义和指定数据库表之间的关联    __tabelname__ = “user”    # 创建字段类型    id = Column(Integer, primary_key=True)    name = Column(String(50))    age = Column(Integer)

PS:定义的数据类型必须继承自之前创建的BaseModel,同时通过指定tablename确定和数据库中某个数据表之间的关联关系,指定某列类型为primary_key设定的主键,其他就是通过Column指定的自定义属性了。

sqlalchemy会根据指定的tablename和对应的Column列字段构建自己的accessors访问器对象,这个过程可以成为instrumentation,经过instrumentation映射的类型既可以进行数据库中数据的操作了。

3.4.3. 数据类型映射操作

完成了类的声明定义之后,Declarative会通过python的metaclass对当前类型进行操作,根据定义的数据类型创建table对象,构建程序中类型和数据库table对象之间的映射mapping关系

通过类型对象的metadata可以实现和数据库之间的交互,有需要时可以通过metadata发起create table操作,通过Base.metadata.create_all()进行操作,该操作会检查目标数据库中是否有需要创建的表,不存在的情况下创建对应的表

..if __name__ == “__main__”:Base.metadata.create_all()..

3.5. 增加和更新

下面就是核心的数据对象的处理了,在程序代码中根据定义的数据类型创建对象的方式比较简单,执行如下的操作创建一个对象:

$ user = User(name=”tom”, age=18)$ print(user.name)tom

$ print(user.id)None

通过会话对象将对象数据持久化到数据库的操作

$ session.add(user)$ print(user.id)None$ session.commit()$ print(user.id)1

3.6. 查询对象Query

Session是sqlalchemy和数据库交互的桥梁,Session提供了一个Query对象实现数据库中数据的查询操作

3.6.1. 常规查询query

直接指定类型进行查询

user_list = session.query(User)for user in user_list:    print(user.name)

3.6.2. 指定排序查询

通过类型的属性指定排序方式

user_list = session.query(User).order_by(User.id) # 默认顺序user_list = session.query(User).order_by(-User.id) # 指定倒序user_list = session.query(User).order_by(-User.id, User.name) # 多个字段

3.6.3. 指定列查询

指定查询数据对象的属性,查询目标数据

user_list = session.query(User, User.name).all()for u in user_list:    print(u.User, u.name)

3.6.4. 指定列属性别名

对于名称较长的字段属性,可以指定名称在使用时简化操作

user_list = session.query(Usre.name.label(‘n’)).all()for user in user_list:    print(user.n)

3.6.5. 指定类型别名

对于类型名称较长的情况,同样可以指定别名进行处理

from sqlalchemy.orm import aliased

user_alias = aliased(User, name=’u_alias’)user_list = session.query(u_alias, u_alias.name).all()for u in user_list:    print(u.u_alias, u.name)

3.6.6. 切片查询

对于经常用于分页操作的切片查询,在使用过程中直接使用python内置的切片即可

user_list = session.query(User).all()[1:3]..

3.7. 条件筛选filter

前一节中主要是对于数据查询对象query有一个比较直观的感受和操作,在实际使用过程中经常用到条件查询,主要通过filter和filter_by进行操作,重点讲解使用最为频繁的filter条件筛选函数

3.7.1. 等值条件——equals / not equals

# equalssession.query(User).filter(User.id == 1) # 相等判断# not equalssession.query(User).filter(User.name != ‘tom’)# 不等判断

3.7.2. 模糊条件——like

session.query(User).filter(User.name.like(‘%tom%’))

3.7.3. 范围条件——in / not in

# INsession.query(User).filter(User.id.in_([1,2,3,4]))session.query(User).filter(User.name.in_([    session.query(User.name).filter(User.id.in_[1,2,3,4])]))# NOT INsession.query(User).filter(~User.id.in_([1,2,3]))

3.7.4. 空值条件——is null / is not null

# IS NULLsession.query(User).filter(User.name == None)session.query(User).filter(User.name.is_(None)) # pep8# IS NOT NULLsession.query(User).filter(User.name != None)session.query(User).filter(User.name.isnot(None)) # pep8

3.7.5. 并且条件——AND

from sqlalchemy import and_

session.query(User).filter(User.name=’tom’).filter(User.age=12)session.query(User).filter(User.name=’tom’, User.age=12)session.query(User).filter(and_(User.name=’tom’, User.age=12))

3.7.6. 或者条件——OR

from sqlalchemy import or_

session.query(User).filter(or_(User.name=’tom’, User.name=’jerry’))

3.7.7. SQL语句查询

某些特殊情况下,我们也可能在自己的程序中直接使用sql语句进行操作

from sqlalchemy import text

session.query(User).from_statement(text(‘select * from users where name=:name and age=:age’)).params(name=’tom’, age=12).all()

3.8. 查询结果

3.8.1. all()函数返回查询列表

session.query(User).all()

[..]

3.8.2. filter()函数返回单项数据的列表生成器

session.query(User).filter(..)

<..>

3.8.3. one()/one_or_none()/scalar()返回单独的一个数据对象

session.query(User).filter(..).one()/one_or_none()/scalar()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容