当前位置: 首页 > article >正文

Python实战(2)-数据库支持

使用简单的纯文本文件可实现的功能有限。诚然,使用它们可做很多事情,但有时可能还需要额外的功能。你可能希望能够自动完成序列化,此时可求助于shelve和pickle(类似于shelve)​。不过你可能需要比这更强大的功能。例如,你可能想自动支持数据并发访问,即允许多位用户读写磁盘数据,而不会导致文件受损之类的问题。还有可能希望同时根据多个数据字段或属性进行复杂的搜索,而不是采用shelve提供的简单的单键查找。尽管可供选择的解决方案有很多,但如果要处理大量的数据,并希望解决方案易于其他程序员理解,选择较标准的数据库可能是个不错的主意。

本章讨论Python数据库API(一种连接到SQL数据库的标准化方式)​,并演示如何使用这个API来执行一些基本的SQL。最后,本章将讨论其他一些数据库技术。

这里不会提供关系型数据库和SQL语言教程。通过阅读有关数据库(如PostgreSQL、MySQL或本章使用的SQLite)的文档,就应该能够学到你需要知道的知识。如果你以前没有使用过关系型数据库,可参阅www.sqlcourse.com或在网上搜索相关的主题,也可参阅Clare Churcher的著作Beginning SQL Queries, 2nd ed(Apress,2016)​。

本章使用的是简单数据库SQLite,但显然绝非只能使用它。有多种流行的商用数据库,如Oracle和Microsoft SQL Server,还有一些使用广泛而且可靠的开源数据库,如MySQL、PostgreSQL和Firebird。有关Python支持的数据库清单,请参阅https://wiki.python.org/moin/DatabaseInterfaces。数据库也并非只有关系型(SQL)这一种,还有对象数据库[如Zope Object Database(ZODB,http://zodb.org)​]​、基于表格的紧凑数据库[如Metakit(http://equi4.com/metakit)​]​、更简单的键-值数据库[如UNIX DBM(https://docs.python.org/3/library/dbm.html)​]​。另外,还有日益流行的各种NoSQL数据库,如MongoDB(http://mongodb.com)​、Cassandra(http://cassandra.apache.org)和Redis(http://redis.io)​,这些数据库都可使用Python来访问。

本章的重点是低级的数据库交互,但有一些高级库能够让你轻松地完成复杂的工作,要获悉这方面的信息,可参阅http://sqlalchemy.org或http://sqlobject.org,也可在网上搜索Python对象-关系映射器。

Python数据库API

前面说过,有各种SQL数据库可供选择,其中很多都有相应的Python客户端模块(有些数据库甚至有多个)​。所有数据库的大多数基本功能都相同,因此从理论上说,对于使用其中一种数据库的程序,很容易对其进行修改以使用另一种数据库。问题是即便不同模块提供的功能大致相同,它们的接口(API)也是不同的。为解决Python数据库模块存在的这种问题,人们一致同意开发一个标准数据库API(DB API)​。这个API的最新版本(2.0)是在PEP 249(Python Database API Specification v2.0)中定义的,网址为http://python.org/peps/pep-0249.html。本节概述有关该API的基础知识。这里不会涉及其可选部分,因为它们并不适用于所有数据库。有关该API的详细信息,可参阅前面提到的PEP,也可参阅Python官方维基百科中的数据库编程指南(http://wiki.python.org/moin/DatabaseProgramming)​。如果你对这个API的细节不感兴趣,可跳过本节。

全局变量

所有与DB API2.0兼容的数据库模块都必须包含三个全局变量,它们描述了模块的特征。这样做的原因是,这个API设计得很灵活,无需进行太多包装就能配合多种不同的底层机制使用。如果要让程序能够使用多种不同的数据库,可能会比较麻烦,因为需要考虑众多不同的可能性。在很多情况下,一种更现实的做法是检查这些变量,看看给定的模块是否是程序能够接受的。如果不是,就显示合适的错误消息并退出或者引发异常。表13-1总结了这些全局变量。

表13-1 Python DB API的模块属性
在这里插入图片描述

API级别(apilevel)是一个字符串常量,指出了使用的API版本。DB API 2.0指出,这个变量的值为’1.0’或’2.0’。如果没有这个变量,就说明模块不与DB API 2.0兼容,应假定使用的是DB API 1.0。编写代码时,允许这个变量为其他值也没有害处,因为说不定什么时候DB API 3.0就出来了。

线程安全程度(threadsafety)是一个0~3(含)的整数。0表示线程不能共享模块,而3表示模块是绝对线程安全的。1表示线程可共享模块本身,但不能共享连接(参见13.1.3节)​,而2表示线程可共享模块和连接,但不能共享游标。如果你不使用线程(在大多数情况下可能不会是这样的)​,就根本不用关心这个变量。

参数风格(paramstyle)表示当你执行多个类似的数据库查询时,如何在SQL查询中插入参数。'format’表示标准字符串格式设置方式(使用基本的格式编码)​,如在要插入参数的地方插入%s。'pyformat’表示扩展的格式编码,即旧式字典插入使用的格式编码,如%(foo)s。除这些Python风格外,还有三种指定待插入字段的方式:'qmark’表示使用问号,'numeric’表示使用:1和:2这样的形式表示字段(其中的数字是参数的编号)​,而’named’表示使用:foobar这样的形式表示字段(其中foobar为参数名)​。如果你觉得参数样式令人迷惑,也不用担心。编写简单程序时,不会用到它们。如果需要明白特定的数据库是如何处理参数的,可参阅相关的文档。

异常

DB API定义了多种异常,让你能够细致地处理错误。然而,这些异常构成了一个层次结构,因此使用一个except块就可捕获多种异常。当然,如果你觉得一切都正常运行,且不介意出现不太可能出现的错误时关闭程序,可以根本不考虑这些异常。表13-2说明了这个异常层次结构。异常应该在整个数据库模块中都可用。有关这些异常的深入描述,请参阅DB API规范(前面提到的PEP)​。

表13-2 Python DB API指定的异常

在这里插入图片描述

连接和游标

要使用底层的数据库系统,必须先连接到它,为此可使用名称贴切的函数connect。这个函数接受多个参数,具体是哪些取决于要使用的数据库。作为指南,DB API定义了表13-3所示的参数。推荐将这些参数定义为关键字参数,并按表13-3所示的顺序排列。这些参数都应该是字符串。

表13-3 函数connect的常用参数
在这里插入图片描述

函数connect返回一个连接对象,表示当前到数据库的会话。连接对象支持表13-4所示的方法。

表13-4 连接对象的方法
在这里插入图片描述

方法rollback可能不可用,因为并非所有的数据库都支持事务(事务其实就是一系列操作)​。可用时,这个方法撤销所有未提交的事务。

方法commit总是可用的,但如果数据库不支持事务,这个方法就什么都不做。关闭连接时,如果还有未提交的事务,将隐式地回滚它们——但仅当数据库支持回滚时才如此!如果你不想依赖于这一点,应在关闭连接前提交。只要提交了所有的事务,就无需操心关闭连接的事情,因为作为垃圾被收集时,连接会自动关闭。然而,为安全起见,还是调用close吧,因为这样做不需要长时间敲击键盘。

说到方法cursor,就必须说说另一个主题:游标对象。你使用游标来执行SQL查询和查看结果。游标支持的方法比连接多,在程序中的地位也可能重要得多。表13-5概述了游标的方法,而表13-6概述了游标的属性。

表13-5 游标对象的方法
在这里插入图片描述

表13-6 游标对象的属性

在这里插入图片描述

有些方法将在本章后面详细讨论,还有一些(如setinputsizes和setoutputsizes)则不会讨论。有关这些方法的详细信息,请参阅前面提到的PEP。

类型

对于插入到某些类型的列中的值,底层SQL数据库可能要求它们满足一定的条件。为了能够与底层SQL数据库正确地互操作,DB API定义了一些构造函数和常量(单例)​,用于提供特殊的类型和值。例如,要在数据库中添加日期,应使用相应数据库连接模块中的构造函数Date来创建它,这让连接模块能够在幕后执行必要的转换。每个模块都必须实现表13-7所示的构造函数和特殊值。有些模块可能没有完全遵守这一点。例如,接下来将讨论的模块sqlite3就没有导出表13-7中特殊值(从STRING到ROWID)​。

表13-7 DB API构造函数和特殊值

在这里插入图片描述


http://www.kler.cn/a/593521.html

相关文章:

  • 【AWS入门】Amazon EC2简介
  • Docker进阶篇1:什么是Docker数据卷?为什么需要Docker数据卷?Docker数据卷3种类型介绍
  • Excel Script Lab学习笔记
  • Vlan初级实验
  • 一次Milvus迁移的记录
  • 【32】单片机编程核心技巧:Switch驱动按键控制跑马灯方向
  • RabbitMQ 基本原理详解
  • Java 并发集合:ConcurrentHashMap 深入解析
  • html5基于Canvas的经典打砖块游戏开发实践
  • 齿轮热处理学习笔记分享
  • 本地部署deepseek-r1建立向量知识库和知识库检索实践【代码】
  • 多模态大模型:将音频向量化
  • 再学:合约继承 、抽象合约 solidity接口、库、事件 合约重入攻击
  • 快速迭代:利用 nodemon 和其他工具实现 Express.js 热更新
  • Wi-Fi NAN 架构(Wi-Fi Aware Specification v4.0,第2章:2.3~2.6)
  • python|exm5-3re模块,正则表达式概念介绍|match()、search()、findall()、sub()、split()
  • LoRA中黑塞矩阵、Fisher信息矩阵是什么
  • python主成分分析法1
  • python函数的多种参数使用形式
  • vue+echarts实现饼图组件(实现左右联动并且数据量大时可滚动)