Python 中有很多连接数据库的模块,pymysql、psycopg2、sqlite3 等,但是通常情况下我们都不会单独使用它们,因为程序可能需要支持多个数据库,而且直接通过调用 SQL 的方式去获取数据库中的数据会使得代码维护成本变高,这种情况下可能就要用到 ORM (数据关系映射, Object Relational Mapping),而 Python 中最著名的 ORM 当属 SQLAlchemy 了
SQLAlchemy 的关系映射提供了 数据库中的表 与 Python 的类、实例之间的映射关系 一般个类对应一张表,一个实例对应一列
SQLAlchemy 基础
首先我们肯定得先安装 SQLAlchemy
| pip install sqlalchemy | 
连接数据库
| from sqlalchemy import create_engine | 
关于连接数据库的 url 可以看官方文档 database-url
Mapping
如果我们需要一张 users 的表,那么我们可以通过一个 User 类来声明它的元数据,它继承自 Base 基类
它有以下几个字段
- username
- location
| from sqlalchemy import create_engine, Column, String, Integer | 
上面的代码用来声明一个数据表的元数据,可以通过 User.__table__ 看看
会返回一个 Table 对象,我们并没有定义 __table__,但是为什么会有这个属性呢?这都是通过 Base 的元类DeclarativeMeta  来完成的
| User.__table__ | 
创建 Schema
users 表定义了,我们该如何创建呢?可以通过 Metadata 类的 create_all 方法来创建数据表的 schema
| Base.metadata.create_all(bind=engine) # 由于指定了 echo 参数,所以打印出创建过程 | 
创建 instance
我们已经创建了一张表,怎么给它加字段呢?其实添加一个字段就像新建一个实例一样简单
| anyisalin = User(username='AnyISalIn', email='anyisalin@gmail.com', location='ShangHai/China') | 
CRUD 操作
create
虽然我们添加了一个字段,但是并没有将它保存到数据库中,如果我们需要 存储、查询、更新数据,那么我们就需要定义 Session 类了
| from sqlalchemy.orm import sessionmaker | 
通过 add 方法将实例临时存储在 Session 对象里面,然后通过 commit 方法提交到数据库,其实 Session 对象的操作就是在进行事务,当然也可以 rollback
| session.add(anyisalin) | 
read
这里先不介绍读取操作了,后面介绍查询
update
如果想要更新字段的数据,其实也非常简单
| anyisalin.username | 
delete
想要删除字段,调用 delete 方法就可以了
| session.delete(anyisalin) | 
查询
我们先添加一点假的数据以供查询
| from faker import Faker # 使用 faker 这个模块来生成一些假数据, pip install faker | 
生成假数据
| fake_data_generate(User, session) | 
基础查询
| session.query(User) #指定查询的字段, 如果只指定了表,则会查询所有字段,相当于 select * from table | 
all
返回所有的字段
| session.query(User).all() | 
first
返回第一个字段
| session.query(User).first() | 
filter
很多时候需要过滤一些条件,可以通过 filter 方法来实现
| session.query(User).filter(User.id == 1) | 
count
计数
| session.query(User).count() | 
还没写
relationship
如果我们需要将用户的 email 单独存放在一张表里面,并使它们的实例都有一定关联关系,我们就需要定义 relationship 字段了
这是一个简单的例子
| from sqlalchemy import Column, String, Integer, create_engine, ForeignKey | 
测试
| Base.metadata.create_all(bind=engine) |