Python SQLAlchemy入门教程(基本用法)

摘要:
本文将以Mysql举例,介绍sqlalchemy的基本用法。其中,Python版本为2.7,sqlalchemy版本为1.1.6。一.介绍SQLAlchemy是Python中最有名的ORM工具。特点是操纵Python对象而不是SQL查询,也就是在代码层面考虑的是对象,而不是SQL,体现的是一种程序化思维,这样使得Python程序更加简洁易读。具体的实现方式是将数据库表转换为Python类,其中数据列作为属性,数据库操作作为方法。sessionsqlalchemy中使用session用于创建程序和数据库之间的会话,所有对象的载入和保存都需要通过session对象。

本文将以Mysql举例,介绍sqlalchemy的基本用法。其中,Python版本为2.7,sqlalchemy版本为1.1.6。

一. 介绍

SQLAlchemy是Python中最有名的ORM工具。

关于ORM:

全称Object Relational Mapping(对象关系映射)。

特点是操纵Python对象而不是SQL查询,也就是在代码层面考虑的是对象,而不是SQL,体现的是一种程序化思维,这样使得Python程序更加简洁易读。

具体的实现方式是将数据库表转换为Python类,其中数据列作为属性,数据库操作作为方法。

优点:

  • 简洁易读:将数据表抽象为对象(数据模型),更直观易读
  • 可移植:封装了多种数据库引擎,面对多个数据库,操作基本一致,代码易维护
  • 更安全:有效避免SQL注入

为什么要用sqlalchemy?

虽然性能稍稍不及原生SQL,但是操作数据库真的很方便!

二. 使用

概念和数据类型

概念

概念对应数据库说明
Engine连接

驱动引擎

Session连接池,事务

由此开始查询

Model

类定义
Column

Query

若干行

可以链式添加多个条件

常见数据类型

数据类型数据库数据类型python数据类型说明
Integerintint整形,32位
Stringvarcharstring字符串
Texttextstring长字符串
Floatfloatfloat浮点型
BooleantinyintboolTrue / False
Datedate

datetime.date

存储时间年月日
DateTimedatetimedatetime.datetime存储年月日时分秒毫秒等
Timetimedatetime.datetime存储时分秒

创建数据库表

1.安装

pip install SQLalchemy

2. 创建连接

from sqlalchemy import create_engine
 
engine = create_engine("mysql://user:password@hostname/dbname?charset=uft8")

这行代码初始化创建了Engine,Engine内部维护了一个Pool(连接池)和Dialect(方言),方言来识别具体连接数据库种类。

创建好了Engine的同时,Pool和Dialect也已经创建好了,但是此时并没有真正与数据库连接,等到执行具体的语句.connect()等时才会连接到数据库。

create_engine还有其它可选的参数,比如:

engine = create_engine("mysql://user:password@hostname/dbname?charset=uft8",
            echo=True,
            pool_size=8,
            pool_recycle=60*30
            )
  • echo: 当设置为True时会将orm语句转化为sql语句打印,一般debug的时候可用
  • pool_size: 连接池的大小,默认为5个,设置为0时表示连接无限制
  • pool_recycle: 设置时间以限制数据库多久没连接自动断开

3. 创建数据库表类(模型)

前面有提到ORM的重要特点,那么我们操作表的时候就需要通过操作对象来实现,现在我们来创建一个类,以常见的用户表举例:

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Users(Base):
  __tablename__ = "users"

  id = Column(Integer, primary_key=True)
  name = Column(String(64), unique=True)
  email = Column(String(64))
  def __init__(self, name, email):
    self.name = name
    self.email = email 

declarative_base()是sqlalchemy内部封装的一个方法,通过其构造一个基类,这个基类和它的子类,可以将Python类和数据库表关联映射起来。

数据库表模型类通过__tablename__和表关联起来,Column表示数据表的列。

4. 生成数据库表

Base.metadata.create_all(engine)

创建表,如果存在则忽略,执行以上代码,就会发现在db中创建了users表。

操作数据

表创建好了就是操作数据了,常见的操作增删改查,我们一一介绍。

session

sqlalchemy中使用session用于创建程序和数据库之间的会话,所有对象的载入和保存都需要通过session对象 。

通过sessionmaker调用创建一个工厂,并关联Engine以确保每个session都可以使用该Engine连接资源:

from sqlalchemy.orm import sessionmaker

# 创建session
DbSession = sessionmaker(bind=engine)
session = DbSession()

session的常见操作方法包括:

  • flush:预提交,提交到数据库文件,还未写入数据库文件中
  • commit:提交了一个事务
  • rollback:回滚
  • close:关闭

举个最简单的例子:

add_user = Users("test", "test123@qq.com")
session.add(add_user)
session.commit()

session.add()将会把Model加入当前session维护的持久空间(可以从session.dirty看到)中,直到commit时提交到数据库。

Q1:add之后如何直接返回对象的属性?

可以在add之后执行db.session.flush(),这样便可在session中get到对象的属性。

Q2:如何进行批量插入,性能比较?

批量插入共有以下几种方法,对它们的批量做了比较,分别是:

session.add_all() < bulk_save_object() < bulk_insert_mappings() < SQLAlchemy_core()

查询是最常用的一个操作了,举个最简单的查询例子:

users = session.query(Users).filter_by(id=1).all()
for item in users:
  print(item.name)

通常我们通过以上查询模式获取数据,需要注意的是,通过session.query()我们查询返回了一个Query对象,此时还没有去具体的数据库中查询,只有当执行具体的.all(),.first()等函数时才会真的去操作数据库。

其中,query有filter和filter_by两个过滤方法,上述例子也可写为:

users = session.query(Users).filter_by(Users.id == 1).all()

通常这两个方法都会用到的,所以一定要掌握它们的区别:

filter filter_by支持所有比较运算符,相等比较用比较用==只能使用"=","!="和"><"过滤用类名.属性名过滤用属性名不支持组合查询,只能连续调用filter变相实现参数是**kwargs,支持组合查询支持and,or和in等

更新数据有两种方法,一种是使用query中的update方法:

filterfilter_by
支持所有比较运算符,相等比较用比较用==只能使用"=","!="和"><"
过滤用类名.属性名

过滤用属性名

过滤用类名.属性名参数是**kwargs,支持组合查询
支持and,or和in等

更新数据有两种方法,一种是使用query中的update方法:

session.query(Users).filter_by(id=1).update({'name': "Jack"})

另一种是操作对应的表模型:

users = session.query(Users).filter_by(name="Jack").first()
users.name = "test"
session.add(users)

这两种方式呢,一般批量更新的话我会选前者,而要对查询获取对象属性之后再更新的场景就需要使用后者。

和更新数据类似,删除数据也有两种方法,第一种:

delete_users = session.query(Users).filter(Users.name == "test").first()
if delete_users:
  session.delete(delete_users)
  session.commit()

第二种:

session.query(Users).filter(Users.name == "test").delete()
session.commit()

批量删除时推荐使用第二种。

以上,就是Python sqlalchemy的基本用法。

代码可参照:my github


1.基本用法

1.安装

安装sqlalchemy

pip3 install sqlalchemy
pip3 install pymysql

本文使用MySQL作为数据库,使用pymysql作为驱动,因此需要安装pymysql

2.连接数据库

1.配置信息

在连接数据库前,需要使用到一些配置信息,然后把它们组合成满足以下条件的字符串:

dialect+driver://username:password@host:port/database
  • dialect:数据库,如:sqlite、mysql、oracle等
  • driver:数据库驱动,用于连接数据库的,本文使用pymysql
  • username:用户名
  • password:密码
  • host:IP地址
  • port:端口
  • database:数据库
HOST = 'localhost'
PORT = 3306
USERNAME = 'root'
PASSWORD = '123456'
DB = 'myclass'

# dialect + driver://username:passwor@host:port/database
DB_URI = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DB}'

建议将配置信息放到你的配置文件中,如config.py

2.创建引擎并连接数据库

from sqlalchemy import create_engine
from config import DB_URI


engine = create_engine(DB_URI)  # 创建引擎
conn = engine.connect()  # 连接
result = conn.execute('SELECT 1')  # 执行SQL
print(result.fetchone())  
conn.close()  # 关闭连接

3.创建ORM模型并映射到数据库中

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from config import DB_URI

engine = create_engine(DB_URI)
Base = declarative_base(engine)  # SQLORM基类
session = sessionmaker(engine)()  # 构建session对象


class Student(Base):
    __tablename__ = 'student'  # 表名
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50))
    age = Column(Integer)
    sex = Column(String(10))


Base.metadata.create_all()  # 将模型映射到数据库中

执行上面代码,将会在数据库中生成对应的映射表student。

4.新增数据

创建表后,接下来我们要添加数据,代码如下:

student = Student(name='Tony', age=18, sex='male')  # 创建一个student对象
session.add(student)  # 添加到session
session.commit()  # 提交到数据库

也可以批量添加数据:

session.add_all([
    Student(name='Jane', age=16, sex='female'),
    Student(name='Ben', age=20, sex='male')
])
session.commit()

4.查询数据

sqlalchemy提供了query()方法来查询数据

获取所有数据

item_list = session.query(Student).all()
print(item_list)
for item in item_list:
    print(item.name, item.age)

执行结果如下

[<mymodel.Student object at 0x000002A0E6A38088>, <mymodel.Student object at 0x000002A0E6A38208>, <mymodel.Student object at 0x000002A0E6A38288>]
Tony 18
Jane 16
Ben 20

查询得到的item_list是一个包含多个Student对象的列表

指定查询列

item_list = session.query(Student).all()
print(item_list)
for item in item_list:
    print(item.name, item.age)

执行结果如下

[<mymodel.Student object at 0x000002A0E6A38088>, <mymodel.Student object at 0x000002A0E6A38208>, <mymodel.Student object at 0x000002A0E6A38288>]
Tony 18
Jane 16
Ben 20

查询得到的item_list是一个包含多个Student对象的列表

指定查询列

item_list = session.query(Student.name).all()
print(item_list)

# [('Tony',), ('Jane',), ('Ben',)]

获取返回数据的第一行

item = session.query(Student.name).first()
print(item)  

# ('Tony',)

使用filter()方法进行筛选过滤

item_list = session.query(Student.name).filter(Student.age >= 18).all()
print(item_list)

# [('Tony',), ('Ben',)]

使用order_by()进行排序

item_list = session.query(Student.name, Student.age).order_by(Student.age.desc()).all() # desc()表示倒序
print(item_list)

# [('Ben', 20), ('Tony', 18), ('Jane', 16)]

多个查询条件(and和or)

# 默认为and, 在filter()中用,分隔多个条件表示and
item_list = session.query(Student.name, Student.age, Student.sex).filter(
    Student.age >= 10, Student.sex == 'female'
).all()
print(item_list)  # [('Jane', 16, 'female')]



from sqlalchemy import or_

# 使用or_连接多个条件
item_list = session.query(Student.name, Student.age, Student.sex).filter(
    or_(Student.age >= 20, Student.sex == 'female')
).all()
print(item_list)  # [('Jane', 16, 'female'), ('Ben', 20, 'male')]

equal/like/in

# 等于
item_list = session.query(Student.name, Student.age, Student.sex).filter(
    Student.age == 18
).all()
print(item_list)  # [('Tony', 18, 'male')]

# 不等于
item_list = session.query(Student.name, Student.age, Student.sex).filter(
    Student.age != 18
).all()
print(item_list)  # [('Jane', 16, 'female'), ('Ben', 20, 'male')]

# like
item_list = session.query(Student.name, Student.age, Student.sex).filter(
    Student.name.like('%To%')
).all()
print(item_list)  # [('Tony', 18, 'male')]

# in
item_list = session.query(Student.name, Student.age, Student.sex).filter(
    Student.age.in_([16, 20])
).all()
print(item_list) # [('Jane', 16, 'female'), ('Ben', 20, 'male')]

count计算个数

count = session.query(Student).count()
print(count)  # 3

切片

item_list = session.query(Student.name).all()[:2]
print(item_list)  # [('Tony',), ('Jane',)]

4.修改数据

修改数据可以使用update()方法,update完成后记得执行session.commit()

# 修改Tony的age为22
session.query(Student).filter(Student.name == 'Tony').update({'age': 22})
session.commit()

item = session.query(Student.name, Student.age).filter(Student.name == 'Tony').first()
print(item) 

执行结果如下

('Tony', 22)

4.删除数据

删除数据使用delete()方法,同样也需要执行session.commit()提交事务

# 删除名称为Ben的数据
session.query(Student).filter(Student.name == 'Ben').delete()
session.commit()

item_list = session.query(Student.name, Student.age).all()
print(item_list)

执行结果如下

[('Tony', 22), ('Jane', 16)]

免责声明:文章转载自《Python SQLAlchemy入门教程(基本用法)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇sublime使用手册交换机二层端口隔离配置详解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python-PyCharm几个设置小技巧

1、设置默认建python的模板 如下图所示: 代码如下:记得引用变量是大写 ##!/usr/bin/python3#-*- coding:utf-8 -*-#@Time :${DATE} ${TIME}#@Author :叮当#@File : ${NAME}.py 2、怎样获取当前文件路径 ctrl+shift+C 3、重命名一个文件 右键-ref...

HP11.31安装11.2.0.3实施手册

1 前言 此文档详细描述了Oracle 11gR2 数据库在HP11.31上的安装RAC的检查及安装步骤。文档中#表示root用户执行,$表示grid或oracle用户执行。 2 系统环境 操作系统环境 说明项 节点1 节点2 硬件型号 ia64 hp Integrity BL860c i2 ia64 hp Integrity BL860c i2...

HeidiSQL安装和使用教程

HeidiSQL 是一个功能非常强大的 MySQL 客户端软件,我们通过它来操作MySQL数据库,比直接通过命令行工具操作要简单的多。我们使用HidiSQL来连接MySQL数据库,MySQL数据库的安装可以参考下文。  百度搜索HeidiSQL的官网,点击Downloads—>HeidiSQL 9.4 Installer,官网已经有中文汉化版本...

Python 100行代码实现2048小游戏

首先我们来看看我们效果图:  这是最简版后期可以去优化,后端自己写一个可视化页面,或者配上一个前端,可以使我们的程序变得更绚丽。 下面我们开始我们的代码 一、构造一个把0元素移至末尾的函数 [2, 4, 0, 2] --> [2, 4, 2, 0] 1 def zero_end(): 2 """ 3 0元素移至到末尾 4...

Python生成pyd文件

Python的脚本文件是开源的,量化策略的安全性没有保障。因此需要保护源码。那么要对Python代码进行混淆、加密保护。 混淆代码,我准备使用pyminifier。而加密处理,就比较麻烦。 Python有py、pyc、pyw、pyo、pyd等文件格式。 其中,pyc是二进制文件。但很容易被反编译。 pyw也不行,只是隐藏命令行界面而已,可以作为入口脚本。...

用Cookie和Session实现用户登录 函数

由于网页是一种无状态的连接程序,你无法得知用户的浏览状态,必须通过Cookie或Session记录用户的有关信息。 Cookie: 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。 PHP透明地支持HTTP Cookie。从客户端发送的Cookie都会被PHP5 包括进$_COOKIE的全局数组。 Session: Session储存于服务端(默...