Python MySQLdb module 学习例子

这篇文章是准备hack in ztc关于mysql监控代码的先期工作。
zabbix监控的好处不用多数,ztc作为zabbix的扩展非常灵活强大,但包含的东西太多,mysql方面显得不是很专精,里面的指标获取都是通show global status like '%xxx'获取,有时候这回显得很乏力。
这时我需要hack in ztc mysql的部分,扩展它,但是mysqldb的模块我用的不是很熟悉。google了很多文章,发现一片很适合切入的教程文章。地址是:http://zetcode.com/db/mysqlpython/
博主很专业,有很多其他类似的教程,不一一枚举了。下面是正文的翻译,细节翻译得不好, 请见谅。

开始前,准备mysql的环境。

apt-get install mysql-server mysql-common mysql-client -y
$ 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


我们不知道对应mysqldb 模块的包的名字,可以使用apt-cache解决
apt-get install python-mysqldb
现在我们已经安装了mysql的python接口。包含了_mysql 和MySQLdb的模块。
下面我们需要创建一个数据库和相对应的用户名
root@ubuntu:~# mysql -u root -p123456
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8004
Server version: 5.5.34-0ubuntu0.12.04.1 (Ubuntu)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database testdb;
Query OK, 1 row affected (0.00 sec)
mysql> create user 'testuser'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.15 sec)
mysql> use testdb;
Database changed
mysql> grant all on testdb.* to 'testuser'@'localhost';
Query OK, 0 rows affected (0.05 sec)
mysql> quit
Bye

_mysql 模块
_mysql模块是直接调用的MySQL C api,跟python db api 接口没有必然联系
通常, 程序员们都倾向于使用MySQLdb模块,我们稍后再看。

现在先看下关于_mysql模块的例子

#!/usr/bin/env python
# -*- coding: utf-8 -*-
                                                                                                                                                                                                                                                                                                                                                                                 
import _mysql
import sys
                                                                                                                                                                                                                                                                                                                                                                                 
try:
con = _mysql.connect('localhost', 'testuser', '123456', '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数据库的版本,sql采用的是 'select version();'
代码地址:https://gist.github.com/stefanmonkey/8312902

MySQLdb 模块
MySQLdb 是围绕_mysql构建的瘦python包装(原文:MySQLdb is a thin Python wrapper around _mysql)
它与Python DB API协同工作. 这个模块是首选与mysql一起工作的模块
第一个例子

这个例子同样是得到mysql 数据库的版本

#!/usr/bin/env python
# -*- coding: utf-8 -*-
                                                                                                                                                                                                                                                                                    
import MySQLdb as mdb
import sys
                                                                                                                                                                                                                                                                                    
try:
con = mdb.connect('localhost', 'testuser', '123456', 'testdb')
                                                                                                                                                                                                                                                                                    
cur = con.cursor()
cur.execute('select version()')
                                                                                                                                                                                                                                                                                    
ver = cur.fetchone()
                                                                                                                                                                                                                                                                                    
print "Database version : %s " % ver
                                                                                                                                                                                                                                                                                    
except mdb.Error, e:
                                                                                                                                                                                                                                                                                    
print "Error %d: %s" % (e.args[0], e.args[1])
sys.exit(1)
                                                                                                                                                                                                                                                                                    
finally:
                                                                                                                                                                                                                                                                                    
if con:
con.close()


代码地址:https://gist.github.com/stefanmonkey/8312907

因为我们接收到只有一个记录,所以我们调用fetchone()方法
在ubuntu环境下执行 会是这个样子
root@ubuntu:~# python MySQLdb.py
Database version : 5.5.34-0ubuntu0.12.04.1 

创建表并加上加上一些数据

#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
con = mdb.connect('localhost', 'testuser', '123456', 'testdb');
with con:
                                                                                                                                                                                                                                                                                 
    cur = con.cursor()
    cur.execute("DROP TABLE IF EXISTS Writers")
    cur.execute("CREATE TABLE 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')")
代码地址:https://gist.github.com/stefanmonkey/8312916
执行结果如下:
root@ubuntu:~# python table.py
table.py:11: Warning: Unknown table 'Writers'
  cur.execute("DROP TABLE IF EXISTS Writers")
这个warning处,具体是我们使用了with语句,它可以让python解释器自动释放资源,也可以提供错误处理这里是因为新创建的Writers表,第一个drop就会有错误,脚本很简陋,只是摸索mysqldb的使用,没必要加错误判断
root@ubuntu:~# mysql -u root -p123456
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8768
Server version: 5.5.34-0ubuntu0.12.04.1 (Ubuntu)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use testdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| Writers          |
+------------------+
1 row in set (0.00 sec)
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>

接收数据

#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
con = mdb.connect('localhost', 'testuser', '123456', 'testdb');
with con:
    cur = con.cursor()
    cur.execute("SELECT * FROM Writers")
    rows = cur.fetchall()
    for row in rows:
        print row


代码地址:https://gist.github.com/stefanmonkey/8312969
rows = cur.fetchall()fetchall()方法得到所有记录。它返回一个结果集。
从技术上讲, 是一个嵌套的元组。每一个内嵌的元组代表表里面的一行

 执行结果如下:
root@ubuntu:~# python get_data.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
con = mdb.connect('localhost', 'testuser', 'test623', 'testdb');
with con:
    cur = con.cursor()
    cur.execute("SELECT * FROM Writers")
    for i in range(cur.rowcount):
                                                                                                                                                                                                                                                     
        row = cur.fetchone()
        print row[0], row[1]


代码地址:https://gist.github.com/stefanmonkey/8313022
rowcount属性会返回sql执行后得到的行数


字典游标
在MySQLdb模块中,有多个游标类型。默认的游标以嵌套元组返回数据。当我们使用字典游标时, 数据会以python字典的形式获取,以这种方式为基础,我们可以根据列名获取数据

#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
con = mdb.connect('localhost', 'testuser', '123456', 'testdb')
with con:
    cur = con.cursor(mdb.cursors.DictCursor)
    cur.execute("SELECT * FROM Writers LIMIT 4")
    rows = cur.fetchall()
    for row in rows:
        print row["Id"], row["Name"]


代码地址:https://gist.github.com/stefanmonkey/8313196
cur = con.cursor(mdb.cursors.DictCursor)表示使用字典游标(dictionary cursor)

执行结果:

python dictcur.py
1 Jack London
2 Honore de Balzac
3 Lion Feuchtwanger
4 Emile Zola



列名 接下来我们会示范,怎样从数据库的表中,同时打印数据和对应的列名

#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
con = mdb.connect('localhost', 'testuser', '123456', 'testdb')
with con:
    cur = con.cursor()
    cur.execute("SELECT * FROM Writers LIMIT 5")
    rows = cur.fetchall()
    desc = cur.description
    print "%s %3s" % (desc[0][0], desc[1][0])
    for row in rows:   
        print "%2s %3s" % row

代码地址:https://gist.github.com/stefanmonkey/8313251desc = cur.descriptiondescription属性返回查询结果的每一个列名

print "%s %3s" % (desc[0][0], desc[1][0])格式化打印表的列名
运行结果如下:
python columnheaders.py
Id Name
 1 Jack London
 2 Honore de Balzac
 3 Lion Feuchtwanger
 4 Emile Zola
 5 Truman Capote


预设语句
利用占位符创建预设语句。Python DB API指南建议5中不同的方式创建预设语句。MySQLdb模块支持其中一种.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
con = mdb.connect('localhost', 'testuser', 'test623', 'testdb')
                                                                                                                                                                                                         
with con:   
    cur = con.cursor()
                                                                                                                                                                                                             
    cur.execute("UPDATE Writers SET Name = %s WHERE Id = %s",
        ("Guy de Maupasant", "4"))       
                                                                                                                                                                                                         
    print "Number of rows updated:",  cur.rowcount


代码地址:https://gist.github.com/stefanmonkey/8313313
执行结果如下:root@ubuntu:~# python prepared.py

Number of rows updated: 1
可以看到数据库中第4行的作家名字已经被修改

mysql> select name from Writers where id =4;
+------------------+
| name             |
+------------------+
| Guy de Maupasant |
+------------------+
1 row in set (0.00 sec)



在mysql中插入图片
图片是二进制数据。Mysql有特殊的数据类型去存储二进制数据,这个类型是BlOB
创建相应的表

mysql> create table images(id int primary key, data mediumblob);Query OK, 0 rows affected (0.01 sec)

#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
def read_image():
                                                                                                                                                                                            
    fin = open("woman.jpg")   
    img = fin.read()
                                                                                                                                                                                            
    return img
                                                                                                                                                                                            
con = mdb.connect('localhost', 'testuser', '123456', 'testdb')
                                                                                                                                                                                         
with con:
                                                                                                                                                                                            
    cur = con.cursor()
    data = read_image()
    cur.execute("INSERT INTO images VALUES(1, %s)", (data, ))

代码地址:https://gist.github.com/stefanmonkey/8313445
执行即可图片是与脚本在同一目录 图片名称修改下即可

读取图片

#!/usr/bin/python
# -*- coding: utf-8 -*-
import MySQLdb as mdb
def writeImage(data):
                                                                                                                                                                                    
    fout = open('woman2.jpg', 'wb')
                                                                                                                                                                                    
    with fout:
                                                                                                                                                                                        
        fout.write(data)
con = mdb.connect('localhost', 'testuser', 'test623', 'testdb')
with con:
    cur = con.cursor()
    cur.execute("SELECT Data FROM Images WHERE Id=1")
    data = cur.fetchone()[0]
    writeImage(data)

代码地址:https://gist.github.com/stefanmonkey/8313476
执行后  我们在当前目录就有了woman2.jpg ,这个是woman.jgp是一样的哦

事务支持待续
事务支持的部分回去慢慢品味
接下来就是扫下mysql的书看下哪些有用的性能指标,然后加进ztc让zabbix欢快地跑起来


你可能感兴趣的:(python,Module,mysqldb,学习例子)