Python数据库操作SQLAlchemy的⽰例代码
程序在运⾏过程中所有的的数据都存储在内存 (RAM) 中,「RAM 是易失性存储器,系统掉电后 RAM 中的所有数据将全部丢失」。在⼤多数情况下我们希望程序运⾏中产⽣的数据能够长久的保存,此时我们就需要将数据保存到磁盘上,⽆论是保存到本地磁盘,还是通过⽹络保存到服务器上,最终都会将数据写⼊磁盘⽂件。将数据保存在磁盘中我们需要⾯对⼀个数据格式的问题,此时就需要引⼊数据库操作。
数据库是专门⽤于数据的集中存储和查询的软件,它便于程序保存和读取数据,且能够通过特定的条件查询指定的数据。
Python 的标准数据库接⼝为 Python DB-API,它为编程⼈员提供了完善的数据库应⽤标称接⼝。但是使⽤ Python DB-API 需要开发⼈员⾃⾏去拼接 SQL,并把 SQL 做成模板。此时全靠编程⼈员来保证系统的安全性,完全有⼈来保证系统的安全性,不可避免的会出现错误,为了减少⼈为原因产⽣的错误 ORM 框架应运⽽⽣。
ORM 即 Object-Relational Mapping,把关系数据库的表结构映射到对象上⾯。负责这个转换过程的就是 ORM 框架
Python 中的 ORM 框架主要有 SQLObject、Storm、Django's ORM、peewee、SQLALchemy。每种 ORM 框架都有各⾃的特点和相应的应⽤范围,本⽂主要介绍 SALALchemy,若你对其他框架感兴趣请⾃⾏搜索相关内容。
SQLAlchemy 简介
SQLAlchemy 是⼀个功能强⼤的开源 Python ORM ⼯具包。它提供了 “⼀个知名企业级的持久化模式的,专为⾼效率和⾼性能的数据库访问设计的,改编成⼀个简单的 Python 域语⾔的完整套件”。它采⽤了数据映射模式(像 Java 中的 Hibernate)⽽不是 Active Record 模式(像Ruby on Rails 的 ORM)。
SQLAlchemy。
SQLAlchemy 的优缺点:
优点:
企业级 API,使得代码有健壮性和适应性。
灵活的设计,使得能轻松完成复杂的数据查询。
缺点:
⼯作单元概念不常见。
重量级 API,导致长学习曲线。
SQLAlchemy 应⽤
以下是⼀段使⽤ SQLAlchemy 操作 SQLite 数据库的代码
# -*- coding:utf-8 -*-
from sqlalchemy import (
create_engine,
Column,
Integer,
String,
)
declarative import declarative_base
import sessionmaker
engine = create_engine('sqlite:///./sqlalchemy.sqlite', echo=True)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String)
fullname = Column(String)
nickname = Column(String)
def __repr__(self):
return "<User(name='%s', fullname='%s', nickname='%s')>" % (self.name, self.fullname, self.nickname)
db_session = sessionmaker(bind=engine)
session = db_session()
user1 = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
user2 = User(name='wendy', fullname='Wendy Williams', nickname='windy')
user3 = User(name='mary', fullname='Mary Contrary', nickname='mary')
session.add(user1)
session.add(user2)
session.add(user3)
sessionmit()
user = session.query(User).filter(User.id<2).all()
print(user)
user = session.query(User).filter(User.id<=5).all()
print(user)
user1.name = 'admin'
<(user1)
user4 = User(name='fred', fullname='Fred Flintstone', nickname='freddy')
<(user4)
session.query(User).filter(User.id==2).update({'name':'test'})
user = session.query(User).filter(User.id<=5).all()
print(user)
在以上代码中我们完成了⼀下⼯作:
1. 连接到数据库「本次我们使⽤的是 SQLite 数据库」。
2. 创建数据库表并将其映射到 Python 类上。
3. 创建数据实例,并将其保存到数据库中。
4. 对保存在数据库中的数据进⾏读取和修改。
导⼊ SQLAlchemy 模块并连接到 SQLite 数据库
SQLAlchemy 通过 create_engine 函数来创建数据库连接。create_engine 函数的第⼀个参数是数据了 URL,第⼆个参数 echo 设置为 True 表⽰在程序的运⾏过程中我们可以在控制台看到操作所涉及到的 SQL 语句。
在本次⽰例中我们使⽤的数据库是 SQLite,你也可以使⽤其他数据库。只有在调试状态下将 echo 设置为 True,在⽣产环境请将 echo 设置为 false 或省略 echo 参数。
engine = create_engine('sqlite:///./sqlalchemy.sqlite', echo=True)
create_engine 返回的是⼀个 Engine 实例,它指向数据库的⼀些核⼼接⼝。SQLAlchemy会根据你选择的数据库配置⽽调⽤对应的 DB-API。
create_engine 函数并会不真正建⽴数据库的 DB-API 连接,当调⽤ ute() 或 t() ⽅法时才会建⽴连接。⼤多数情况下我们⽆需关注 Engine,SQLAlchemy 会帮我们处理。
创建数据库表
将 python 类映射到数据库表上,这个 Python 类需要时⼀个指定基类的⼦类,这个基类应当含有ORM映射中相关的类和表的信息。这个基类可以通过 declarative_base ⽅法来创建。
Base = declarative_base()
在这个⽰例中使⽤ Base 基类创建了⼀个 User 的类来作为数据库表。
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String)
fullname = Column(String)
nickname = Column(String)
def __repr__(self):
return "<User(name='%s', fullname='%s', nickname='%s')>" % (self.name, self.fullname, self.nickname)
在 User 类中我们定义了需要映射到数据库表上的属性,主要包括表名称、列的类型和名称等。这个类⾄少应包含⼀个名为 tablename 的属性来给出数据库表的名称,及⾄少⼀个给出表的主键「primary key」的列。在 User 类中我们定义了表名称为 users,定义了 id、name、fullname、nickname 四列数据,并设置 id 为表的主键。
创建完成 User 类后,实际在 SQLite 数据库中并不存在该表,此时需要使⽤ declarative 基类的 ate_all 在数据库中创建 users 表,在 create_all ⽅法中我们需要传⼊参数 Engine。
通过 ate_all 传⼊的 Engine 参数,SQLAlchemy ⾃动实现对数据库的连接。
保存数据实例到数据库中
将数据保存到数据库中,我们需要 User 的实例和⽤于操作数据的 session。
session 是 ORM 数据的接⼝,可以通过 session 来操作数据库中的数据。
使⽤已经定义完成的 User 类将数据实例化。
user1 = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
user2 = User(name='wendy', fullname='Wendy Williams', nickname='windy')
user3 = User(name='mary', fullname='Mary Contrary', nickname='mary')
获取 session ⾸先需要使⽤ sessionmaker 来得到 session 的⼯⼚类,然后通过⼯⼚类来获取 session。
db_session = sessionmaker(bind=engine)
session = db_session()
session 通过 Engine 与数据库进⾏关联。session 创建完成后并不会⽴即打开与数据库的连接,只有当我们第⼀使⽤ session 是,才会从 Engine 维护的连接池中取出⼀个连接来操作数据库,这个连接在我们关闭 session 时会被释放。
获取 session 后可以通过 add 和 commit ⽅法将数据保存到数据库中。
session.add(user1)
session.add(user2)
session.add(user3)
sessionmit()
对数据库中的数据进⾏查询和修改
SQLAlchemy 通过 query 来对数据进⾏查询,可以通过 filter ⽅法对查询结果进⾏筛选。
user = session.query(User).filter(User.id<2).all()
print(user)
user = session.query(User).filter(User.id<=5).all()
print(user)
以上代码通过 query 获取数据库中所有 User 数据,然后通过 filter ⽅法筛选出 id ⼩于 2 和 id ⼩于等于 5 的数据。
数据库的修改可以通过 merge 和 update 来实现
user1.name = 'admin'
<(user1)
user4 = User(name='fred', fullname='Fred Flintstone', nickname='freddy')
<(user4)
session.query(User).filter(User.id==2).update({'name':'test'})
user = session.query(User).filter(User.id<=5).all()
session如何设置和读取
print(user)
使⽤ merge 修改数据,当数据中存在该数据时修改,不存在是将当前数据插⼊数据库中。
代码运⾏结果
以上⽰例代码的运⾏结果如下
2019-02-16 21:45:23,919 ine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
2019-02-16 21:45:23,919 ine.base.Engine ()
2019-02-16 21:45:23,919 ine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
2019-02-16 21:45:23,919 ine.base.Engine ()
2019-02-16 21:45:23,920 ine.base.Engine PRAGMA table_info("users")
2019-02-16 21:45:23,920 ine.base.Engine ()
2019-02-16 21:45:23,921 ine.base.Engine
CREATE TABLE users (
id INTEGER NOT NULL,
name VARCHAR,
fullname VARCHAR,
nickname VARCHAR,
PRIMARY KEY (id)
)
2019-02-16 21:45:23,921 ine.base.Engine ()
2019-02-16 21:45:23,922 ine.base.Engine COMMIT
2019-02-16 21:45:23,924 ine.base.Engine BEGIN (implicit)
2019-02-16 21:45:23,925 ine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,925 ine.base.Engine ('ed', 'Ed Jones', 'edsnickname')
2019-02-16 21:45:23,926 ine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,926 ine.base.Engine ('wendy', 'Wendy Williams', 'windy')
2019-02-16 21:45:23,926 ine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,926 ine.base.Engine ('mary', 'Mary Contrary', 'mary')
2019-02-16 21:45:23,927 ine.base.Engine COMMIT
2019-02-16 21:45:23,929 ine.base.Engine BEGIN (implicit)
2019-02-16 21:45:23,929 ine.base.Engine SELECT users.id AS users_id, user
s.name AS users_name, users.fullname AS users_fullname, users.nickname AS users_nickname
FROM users
WHERE users.id < ?
2019-02-16 21:45:23,929 ine.base.Engine (2,)
[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>]
2019-02-16 21:45:23,931 ine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.nickname AS users_nickname
FROM users
WHERE users.id <= ?
2019-02-16 21:45:23,931 ine.base.Engine (5,)
[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>, <User(name='wendy', fullname
='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>]
2019-02-16 21:45:23,932 ine.base.Engine UPDATE users SET name=? WHERE users.id = ?
2019-02-16 21:45:23,932 ine.base.Engine ('admin', 1)
2019-02-16 21:45:23,933 ine.base.Engine INSERT INTO users (name, fullname, nickname) VALUES (?, ?, ?)
2019-02-16 21:45:23,933 ine.base.Engine ('fred', 'Fred Flintstone', 'freddy')
2019-02-16 21:45:23,934 ine.base.Engine UPDATE users SET name=? WHERE users.id = ?
2019-02-16 21:45:23,934 ine.base.Engine ('test', 2)
2019-02-16 21:45:23,935 ine.base.Engine SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.nickname AS users_nickname
FROM users
WHERE users.id <= ?
2019-02-16 21:45:23,935 ine.base.Engine (5,)
[<User(name='admin', fullname='Ed Jones', nickname='edsnickname')>, <User(name='test', fullname='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>, <User(name='fred', fullname='Fred Flintstone', nickn 由于我们设置 create_engine 中 echo 为 True,因此在执⾏结果中包含了 SQLAlchemy 打印的 SQL 语句,我们可以取消 crete_engine 中的 echo
engine = create_engine('sqlite:///./sqlalchemy.sqlite')
此时的执⾏结果如下:
[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>]
[<User(name='ed', fullname='Ed Jones', nickname='edsnickname')>, <User(name='wendy', fullname='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>]
[<User(name='admin', fullname='Ed Jones', nickname='edsnickname')>, <User(name='test', fullname='Wendy Williams', nickname='windy')>, <User(name='mary', fullname='Mary Contrary', nickname='mary')>, <User(name='fred', fullname='Fred Flintstone', nickn 当取消 echo 后,程序运⾏结果中原有的 SQL 语句消失。
本⽂只是对 SQLAlchemy 的使⽤进⾏简单的介绍,SQLAlchemy 本⾝还有很多特性和运⽤⽅法我们可以共同探讨。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。