目标
使用 SQLAlchemy 连接数据库,创建数据表
使用 SQLAlchemy 实现插入数据、查询数据的操作
环境:
Python==3.6.8
SQLAlchemy==1.2.16
Psycopg2==2.7.6.1
插入一条数据
现在,我们可以直接使用 ORM 来操作数据了,先来插入一条数据:
虽然我们没有指定 的值,但是 仍然有个默认值,SQLAlchemy 的 会在初次访问某个属性的时候赋上默认值。如果已经赋上的值,则会直接使用之前赋予旳值。
这时,我们查一下数据库,看看数据有没有存进去:
???
怎么回事?肯定是漏了哪一步。
SQLAlchemy 是通过 来和数据库交流通信的。
有两种时机来定义 :
一、 之后
二、 之前
然后在需要和数据库交流的时候,可以直接实例化 :
在把数据存入数据库之前,需要先将对象数据加入 之中,可以调用 的 方法:
这时候我们再去查数据库:
没错,数据库其实还不知道有这数据,这个时候,该对象存在于 中,处于 pending 状态,还没有 SQL 语句发送给数据库, 只有在一定的时候才会去发送 SQL 持久化数据(这个过程称为 flush)。
我们现在通过 ORM 来查询下:
Query 查询返回的结果对象居然和之前的对象一样。实际上 发现返回的对象其实和之前对象引用的是内部映射对象中的同一行数据,所以返回的对象其实是同一个内存上的数据。
这个概念称为 ORM 的 ,这能确保一个 上的所有特定行的操作都是操作的同样数据。 中指定 的对象,所有 SQL 查询都会只返回同样的 Python 对象,如果想新建一个已存在的 对象也是会直接报错的。
上述用户的密码太简单了,我们可以直接这样更改:
对象还能检测到 被修改了:
我们再往 添加一条数据:
我们可以通过 的 属性获知还有哪些处于 pending 状态的对象:
以上,所有操作的都是存在 中的数据,现在,终于到了我们梦寐以求的时刻 —— 插入数据库。
通过 的 方法,将所有的数据持久化进数据库:
现在我们去数据库瞅瞅:
完美。
当 将数据插入数据库之后,这些对象属性的值都能立马获取。
在 之后,会开启一个新的事务,所以所有的内部映射对象都会重新加载。SQLAlchemy 默认会在访问本次事务的时候,从上一次事务中刷新数据。
查询
当 对象使用 方法时,会创建一个 对象。
一、 可以接受模型类作为参数,将返回该模型类的实例对象:
二、 也可以接受模型类的字段属性作为参数,返回这些属性值的 tuple:
上面返回的 tuple 可以是命名 tule,也可以是 ,长得和字典差不多。属性的话 key 就是属性名字,类的话就是类名:
当然,如果不想使用上面这些默认的名称,也可以通过 来自定义名字:
而,对于整个类名的自定义命名则需要使用 方法:
的 和 操作,都可以直接使用 Python 的切片实现,同时还可以搭配 使用:
过滤操作有两种:
一、可以通过 传入关键字参数来实现:
二、通过 传入类的映射属性实现:
可以看见,第二种过滤方法更灵活。其传入的是 Python 的操作符。
常用的操作符有以下几种:
is not null:
and:from sqlalchemy import and_
query.filter(and_(User.name=='tom', User.id==2))
query.filter(User.name=='tom', User.id==2)
query.filter(User.name=='tom').filter(User.id==2)
or:from sqlalchemy import or_
query.filter(or_(User.name=='tom', User.id==2))
返回值
一般就分两种:对象列表、对象:
:返回对象列表
:返回第一个对象
:返回一个对象,如果该 query 为空或者 不止一个对象都会报错
:返回一个对象,query 为空返回 None,多个对象还是会报错
:返回一个对象,会先调用 ,获取对象,然后返回第一列的数据,query 为空返回 None,多个对象报错
使用字符SQL
通过 方法,可以接受文字字符串,大部分的 方法都支持:
里面还可以传递变量。变量名前面只需加上 ,然后在配合 方法即可:
如果想直接使用完整的 SQL 语句可以在 中使用 :
另外,可能会有这么一种情况:当我们处理复杂案例时,可能会碰到多个映射类有重复的列名,或者还会有些匿名的 ORM 结构。我们可以使用 方法指定具体列所对应的 ORM 映射:
计数
简单的 计数可以直接使用 :
但是这段语句会翻译成如下的 SQL 命令去执行:
SQLAlchemy 总是会把我们的查询作为子集,然后再从这里面计算行数。
有时候我们可能需要更明确的指定需要计数的内容, 表达式就可以完成:
如果我们想实现简单的 ,可以这么做:
还可以再简化,当我们直接以 主键来计数, 都可以省略不写:
- End -
领取专属 10元无门槛券
私享最新 技术干货