原文链接:http://zetcode.com/databases/mysqlpythontutorial/
翻译作者:kodango dangoakachan at foxmail dot com
译文链接:
a. http://kodango.com/mysql-python-tutorial-part-one
b. http://kodango.com/mysql-python-tutorial-part-two
关于本教程
这是一份介绍用Python语言操作MySQL数据库的教程,覆盖了基础的Python MySQL编程内容。本教程中使用了MySQLdb模块,文中的例子在Ubuntu系统下运行和测试。
译者注:我使用ArchLinux,会在文中添加与ArchLinux相关的内容,例子也会一一在ArchLinux下验证。
在本站中,有许多与本文类似的教程,其中包括PostgreSQL Python,MySQL Visual Basic,MySQL PHP。如果你需要更新与Python语言相关的知识,在这里还有一份完整的Python教程。你也可以考虑阅读MySQL教程。
关于MySQL数据库
MySQL是一个领先的开源数据库管理系统。它是一个多用户,多线程的数据库管理系统。MySQL在网上非常流行,它与Linux、Apache、 PHP一起组成LAMP平台,这是一个非常流行的Web平台。目前,MySQL是由甲骨文拥有。MySQL数据库可用于最重要的几个操作系统上。它能够运 行在BSD UNIX,Linux,Windows或Mac操作系统之上。
Wikipedia和YouTube均使用MySQL数据库。这些站点每天处理数百万的查询次数。MySQL包含服务器系统和嵌入式系统两个版本。
开始之前
我们需要安装几个软件包,才能确保本文的例子可以正确地执行。如果你的电脑上没有安装MySQL,我们必须先安装它:
Ubuntu $ sudo apt-get install mysql-server ArchLinux $ sudo pacman -S mysql 或者 $ yaourt xampp
以上的命令会安装MySQL服务器,还包括一些相关的软件包。在安装的过程中,可能会有提示让你输入MySQL的Root账号的密码。
Ubuntu $ apt-cache search MySQLdb python-mysqldb - A Python interface to MySQL python-mysqldb-dbg - A Python interface to MySQL (debug extension) bibus - bibliographic database eikazo - graphical frontend for SANE designed for mass-scanning ArchLinux # sudo pacman -Ss mysql | grep python extra/mysql-python 1.2.3-3 MySQL support for Python
我们并不知道MySQLdb模块的具体包名称,我们使用apt-cache命令来搜索。
译者注:ArchLinux下用pacman -Ss来搜索。
Ubuntu $ sudo apt-get install python-mysqldb ArchLinux $ sudo pacman -S mysql-python
在这里,我们安装好MySQL数据库的Python编程接口,其中包括_mysql和MySQLdb模块。
接下来,我们会为本文的例子创建一个新的数据库和数据库用户,我们使用MySQL客户端来操作:
$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 30 Server version: 5.0.67-0ubuntu6 (Ubuntu) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | +--------------------+ 2 rows in set (0.00 sec)
译者注:如果是安装Xampp,MySQL客户端位置在/opt/lampp/bin/mysql(具体位置以实际为主)
我们使用root账号连接到数据库上,并用通过SHOW DATABASES语句列出所有数据库名称。
mysql> CREATE DATABASE testdb; Query OK, 1 row affected (0.02 sec)
我们创建一个新的数据库testdb,在本文的例子中都会用到这个数据库。
mysql> CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'test623'; Query OK, 0 rows affected (0.00 sec) mysql> USE testdb; Database changed mysql> GRANT ALL ON testdb.* TO 'testuser'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> quit; Bye
我们创建一个新的数据库用户,并且将testdb数据库中的所有表的操作权限全部授权给这个用户。
_mysql模块
_mysql模块直接封装实现了MySQL的C语言API函数。它与Python标准的数据库API接口不兼容。通常,程序员都更加喜欢面向对象的MySQLdb模块。我们也会更加关注后一个模块。在这里,我们只是给出一个使用_mysql模块编程的小例子。
#!/usr/bin/python # -*- coding: utf-8 -*- import _mysql import sys con = None try: con = _mysql.connect('localhost', 'testuser', 'test623', 'testdb') con.query("SELECT VERSION()") result = con.use_result() print "MySQL version: %s" % \ result.fetch_row()[0] except _mysql.Error, e: print "Error %d: %s" % (e.args[0], e.args[1]) sys.exit(1) finally: if con: con.close()
这个例子会获取并打印MySQL数据库的版本,为此我们使用SELECT VERSION()
这条SQL语句。
MySQLdb模块
MySQLdb是在_mysql模块的基础上进一步进行封装,并且与Python的标准数据库API接口兼容,这使得代码更易于移植。使用这个模块是操作MySQL数据库的首选方法。
第一个例子
在第一个例子中,我们来获取MySQL数据库的版本。
!/usr/bin/python # -*- coding: utf-8 -*- import MySQLdb as mdb import sys con = None try: con = mdb.connect('localhost', 'testuser', 'test623', 'testdb'); cur = con.cursor() cur.execute("SELECT VERSION()") data = cur.fetchone() print "Database version : %s " % data except mdb.Error, e: print "Error %d: %s" % (e.args[0],e.args[1]) sys.exit(1) finally: if con: con.close()
在这个脚本中,我们连接到testdb数据库并执行 SELECT VERSION()
语句。该脚本返回MySQL数据库的版本号,并打印到终端。
import MySQLdb as mdb
我们导入MySQLdb模块。
con = None
我们将con变量初始化成None。在无法创建数据库连接的时候(例如硬盘空间已满),我们不能定义该数据库连接变量。这将会导致在finally语句中执行出错。
con = mdb.connect('localhost', 'testuser', 'test623', 'testdb');
我们连接到数据库中,其中connect()
方法有四个参数。第一个是MySQL数据库所在的主机地址,在我们的例子中为'localhost';第二个参数是数据库的用户名,其实是该用户的密码;最后一个参数是数据库的名称。
cur = con.cursor() cur.execute("SELECT VERSION()")
一旦连接成为,我们将会得到一个cursor(游标)对象。这个cursor对象用来遍历结果集中的记录。我们通过调用该curor对象的execute()
方法来执行SQL语句。
data = cur.fetchone()
我们开始获取数据,由于我们只取回一个记录,因此我们调用fetchone()
方法。
print "Database version : %s " % data
我们将取回的数据打印到终端。
except mdb.Error, e: print "Error %d: %s" % (e.args[0],e.args[1]) sys.exit(1)
我们检查错误,这是很重要的,因为与在与数据库打交道的过程中很容易出错。
finally: if con: con.close()
最后一步,我们释放连接的资源。
$ ./version.py Database version : 5.5.9
输出结果如上所示。
创建并填充表
我们创建一个表,并在其中填入一些数据。
#!/usr/bin/python # -*- coding: utf-8 -*- import MySQLdb as mdb import sys con = mdb.connect('localhost', 'testuser', 'test623', 'testdb'); with con: cur = con.cursor() cur.execute("CREATE TABLE IF NOT EXISTS \ Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))") cur.execute("INSERT INTO Writers(Name) VALUES('Jack London')") cur.execute("INSERT INTO Writers(Name) VALUES('Honore de Balzac')") cur.execute("INSERT INTO Writers(Name) VALUES('Lion Feuchtwanger')") cur.execute("INSERT INTO Writers(Name) VALUES('Emile Zola')") cur.execute("INSERT INTO Writers(Name) VALUES('Truman Capote')")
译者注:在这里使用了with..的语法,在退出with语句之前,会执行con对象的__exit__方法,猜测在该方法中会调用commit方法提交事务,同PySqlite学习笔记介绍的一样。
我们创建一张记录作家名字的数据库表,并往其中添加五位作者。
cur.execute("CREATE TABLE IF NOT EXISTS \ Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))")
这条SQL语句创建了一个名为Writers的新数据库,它包含Id和Name两列。
cur.execute("INSERT INTO Writers(Name) VALUES('Jack London')") cur.execute("INSERT INTO Writers(Name) VALUES('Honore de Balzac')") ...
我们使用INSERT语句插入作者到表中, 这里我们添加两行。
mysql> SELECT * FROM Writers; +----+-------------------+ | Id | Name | +----+-------------------+ | 1 | Jack London | | 2 | Honore de Balzac | | 3 | Lion Feuchtwanger | | 4 | Emile Zola | | 5 | Truman Capote | +----+-------------------+ 5 rows in set (0.00 sec)
在脚本执行之后,我们通过MySQL的客户端工具来查询Writers表中的所有数据。
取回数据
现在,在往表中插入一些数之后,我们想要将数据取回。
#!/usr/bin/python # -*- coding: utf-8 -*- import MySQLdb as mdb import sys con = mdb.connect('localhost', 'testuser', 'test623', 'testdb'); with con: cur = con.cursor() cur.execute("SELECT * FROM Writers") rows = cur.fetchall() for row in rows: print row
在这个例子中,我们从Writers表中取回所有数据。
cur.execute("SELECT * FROM Writers")
这条SQL语句从Writers表中查询所有的数据。
rows = cur.fetchall()
fetchall()
方法获取所有记录。它返回一个结果集,该结果集其实是一个包含元组的元组。在元组内部的第一个元组代码表中的一行。
for row in rows: print row
我们以行的方式将数据打印到终端。
$ ./retrieve.py (1L, 'Jack London') (2L, 'Honore de Balzac') (3L, 'Lion Feuchtwanger') (4L, 'Emile Zola') (5L, 'Truman Capote')
这是本例子的输出结果。
一次性返回所有的数据未必可行,我们可以取逐行依次取回。
#!/usr/bin/python # -*- coding: utf-8 -*- import MySQLdb as mdb import sys con = mdb.connect('localhost', 'testuser', 'test623', 'testdb'); with con: cur = con.cursor() cur.execute("SELECT * FROM Writers") numrows = int(cur.rowcount) for i in range(numrows): row = cur.fetchone() print row[0], row[1]
我们仍然从Writers表中取回数据,并打印到终端。这次我们逐行获取数据。
numrows = int(cur.rowcount)
这里我们首先确认SQL语句查询结果中包含的行数。
for i in range(numrows): row = cur.fetchone() print row[0], row[1]
我们使用fetchone()
方法逐行获取数据。
$ ./retrieve2.py 1 Jack London 2 Honore de Balzac 3 Lion Feuchtwanger 4 Emile Zola 5 Truman Capote
该例子返回的结果。
译者注:由于篇幅有限,余下内容请看下一篇文章。
One comment on “转:MySQL Python 教程(一)”
[…] ← 转:MySQL Python 教程(一) […]