《Python Cookbook(第3版)中文版》——6.8 同关系型数据库进行交互

6.8 同关系型数据库进行交互

6.8.1 问题

我们需要选择、插入或者删除关系型数据库中的行数据。

6.8.2 解决方案

在Python中,表达行数据的标准方式是采用元组序列。例如:

stocks = [
    ('GOOG', 100, 490.1),
    ('AAPL', 50, 545.75),
    ('FB', 150, 7.45),
    ('HPQ', 75, 33.2),
]

当数据以这种形式呈现时,通过Python标准的数据库API(在PEP 249中描述)来同关系型数据库进行交互相对来说就显得很直接了。该API的要点就是数据库上的所有操作都通过SQL查询来实现。每一行输入或输出数据都由一个元组来表示。

为了说明,我们可以使用Python自带的sqlite3模块。如果正在使用一个不同的数据库(如MySQL、Postgres或者ODBC),就需要安装一个第三方的模块来支持。但是,底层的编程接口即使不完全相同的话也几乎是一致的。

第一步是连接数据库。一般来说,要调用一个connect()函数,提供类似数据库名称、主机名、用户名、密码这样的参数以及一些其他需要的细节。示例如下:

>>> import sqlite3
>>> db = sqlite3.connect('database.db')
>>>

要操作数据的话,下一步就要创建一个游标(cursor)。一旦有了游标,就可以开始执行SQL查询了。示例如下:

>>> c = db.cursor()
>>> c.execute('create table portfolio (symbol text, shares integer, price real)')
<sqlite3.Cursor object at 0x10067a730>
>>> db.commit()
>>>

要在数据中插入行序列,可以采用这样的语句:

>>> c.executemany('insert into portfolio values (?,?,?)', stocks)
<sqlite3.Cursor object at 0x10067a730>
>>> db.commit()
>>>

要执行查询操作,可以使用下面这样的语句:

>>> for row in db.execute('select * from portfolio'):
...     print(row)
...
('GOOG', 100, 490.1)
('AAPL', 50, 545.75)
('FB', 150, 7.45)
('HPQ', 75, 33.2)
>>>

如果想执行的查询操作需要接受用户提供的输入参数,请确保用?隔开参数,就像下面的示例这样:

>>> min_price = 100
>>> for row in db.execute('select * from portfolio where price >= ?',
                              (min_price,)):
...     print(row)
...
('GOOG', 100, 490.1)
('AAPL', 50, 545.75)
>>>

6.8.3 讨论

从较低的层次来看,同数据库的交互其实是一件非常直截了当的事。只要组成SQL语句然后将它们传给底层的模块就可以更新数据库或者取出数据了。尽管如此,这里还是有一些比较棘手的细节问题需要针对每种情况逐项考虑。

其中一个比较复杂的问题就是将数据库中的数据映射到Python的类型中。对于像日期这样的条目,最常见的是使用datetime模块中的datetime实例,或者也可能是time模块中用到的系统时间戳(system timestamps)。对于数值型的数据,尤其是涉及小数的金融数据,这些数字可以用decimal模块中的Decimal实例来表示。不幸的是,确切的映射关系会因数据库后端的不同而有所区别,因此必须去阅读相关的文档。

另一个极其重要的问题是需要考虑组成SQL语句的字符串。我们绝对不应该用Python的字符串格式化操作符(即%)或者.format()方法来创建这种字符串。如果给这样的格式化操作符提供的值是来自于用户的输入,那么这就等于将你的程序敞开大门迎接SQL注入攻击(参见http://xkcd.com/327 )。在查询操作中,特殊的?通配符会指示数据库后端启用自己的字符串替换机制,这样才能做到安全(希望如此)。

可悲的是,数据库后端对通配符的支持并不一致。有许多模块采用的是?或%s,而其他一些可能会使用不同的符号,比如用:0或者:1来代表参数。这里再次说明,必须查阅正在使用的数据库模块的文档资料。数据库模块的paramstyle属性中也包含有关于引用样式的相关信息。

对于简单地三趸将数据从数据库表项中取出和输入,使用数据库API通常足够了。如果要处理更加复杂的任务,那么使用一种更高层次的接口就显得很有意义了,比如那些提供有对象关系映射组件(object-relational mapper,ORM)的接口。像SQLAlchemy(http://www.sqlalchemy.org )这样的库允许数据库表项以Python类的形式来描述,在执行数据库操作时可隐藏大部分底层的SQL。

时间: 2024-09-25 07:36:49

《Python Cookbook(第3版)中文版》——6.8 同关系型数据库进行交互的相关文章

《图数据库(第2版)》——2.1 关系型数据库缺少联系

2.1 关系型数据库缺少联系 数十年来,开发者试图使用关系型数据库处理关联的.半结构化的数据集.关系型数据库设计之初是为了处理纸质表格以及表格化结构-有些方面关系型数据库做得非常好-它们试图对这种实际中的特殊联系进行建模.然而讽刺的是,关系型数据库在处理联系上做得却并不好. 联系确实存在于关系型数据库自身的术语中,但只出现在建模阶段,作为连接表的手段.前面章节在对关联数据的讨论中曾经提到,我们经常需要对连接实体的联系进行语义的区分,并为其定义权重.关联关系什么也做不了.更糟糕的是,随着离群数据(

《Python Cookbook(第3版)中文版》——导读

前 言 自2008年以来,我们已经目睹了整个Python世界正缓慢向着Python 3进化的事实.众所周知,完全接纳Python 3要花很长的时间.事实上,就在写作本书时(2013年),大多数Python程序员仍然坚持在生产环境中使用Python 2.关于Python 3不能向后兼容的事实也已经做了许多努力来补救.的确,向后兼容性对于任何已经存在的代码库来说是个问题.但是,如果你着眼于未来,你会发现Python 3带来的好处绝非那么简单. 正因为Python 3是着眼于未来的,本书在之前的版本上

谁有&amp;amp;lt;&amp;amp;lt;CLR Via C#&amp;amp;gt;&amp;amp;gt;第三版中文版的电子书

问题描述 谁有<<CLRViaC#>>第三版中文版的电子书,我是个初学者,看网上推荐此书的人多,想看一下,我的QQ:330784617.谢谢!! 解决方案 解决方案二:试一试我一般看英文的,虽然很少看书:(解决方案三: 解决方案四:第二版有的,想看第三版.

拒绝从入门到放弃_《Python 核心编程 (第二版)》必读目录

目录 目录 关于这本书 必看知识点 最后 关于这本书 <Python 核心编程 (第二版)>是一本 Python 编程的入门书,分为 Python 核心(其实并不核心,应该叫基础) 和 高级主题 两大部分,以 Python 2.x 作为主要演示版本,涵盖的知识面广,知识点较齐全,代码多且好理解,但对 Python 版本特性的内容太久远,不合时宜. 整体来说 Python 核心 部分是主要内容,高级主题 部分作为应用扩展内容.后半部分篇幅较短,内容不够深入,只到了解的层面,好在横向够广(每一个主

(六十二)第四章总结——《C++ Primer Plus 第6版 中文版》

书是<C++ Primer Plus  第6版  中文版> 数组.指针.结构 是C++的3种复合类型.   注:为了方便,类型名用int为主,变量名用a为主.   数组: 包括数组(例如int a[10];)和字符串(例如char a[10];),还有string类(例如string a="abc";),vector类(例如vector<int>a(5)).array类(array<int,3>a)等. 数组名表示数组所在的(第一个元素)内存地址.

求大神解答一下-C++ primer plus 第6版 中文版 第16章复习题的一个问题

问题描述 C++ primer plus 第6版 中文版 第16章复习题的一个问题 奇葩的是课后居然没答案...... 求正规.严谨.简洁的标准答案! 程序清单16.15(在p708页):functor.cpp //functor.cpp--using a functor #include尖括号iostream尖括号 #include尖括号list尖括号 #include尖括号iterator尖括号 #include尖括号algorithm尖括号 template//functor class

【转】c++.primer.plus.第五版.中文版[下载]

c++.primer.plus.第五版.中文版[下载] 一共有5部分.全部下载完才可解压阅读. c++.primer.plus.第五版.中文版(一) c++.primer.plus.第五版.中文版(二) c++.primer.plus.第五版.中文版(三) c++.primer.plus.第五版.中文版(四) c++.primer.plus.第五版.中文版(五) "在遇到无法解决的问题时,我总会求助于C++ Primer一书."--Bruce Eckel,"编程思想"

《SQL初学者指南(第2版)》第1章 关系型数据库和SQL

第1章 关系型数据库和SQLSQL初学者指南(第2版)正如前言中所提到的,在与关系型数据库中的数据进行交互的时候,SQL是使用最广泛的软件工具.在这方面,SQL利用了自身的语言和逻辑两方面的要素.作为一种语言,SQL的独特语法用到了很多的英语单词,诸如WHERE.FROM和HAVING.作为一种逻辑表达,它指定了在关系型数据库中检索和修改数据的细节. 考虑到了这两方面因素,我们在本书中介绍SQL的各个方面的时候,尝试强调语言和逻辑这两部分.在所有语言中,无论它们是计算机语言还是口语,我们都需要学

《Python Cookbook(第2版)中文版》——1.15 扩展和压缩制表符

1.15 扩展和压缩制表符 任务 将字符串中的制表符转化成一定数目的空格,或者反其道而行之. 解决方案 将制表符转换为一定数目的空格是一种很常见的需求,用Python的字符串提供的expandtabs方法可以轻松解决问题.由于字符串不能被改变,这个方法返回的是一个新的字符串对象,是原字符串的一个修改过的拷贝.不过,仍可以将修改过的拷贝绑定到原字符串的名字: mystring = mystring.expandtabs( ) 这样并不会改变mystring原先指向的字符串对象,只不过将名字myst