详细介绍Python 操作MySQL数据库

jopen 8年前

 此篇随笔是 Python 操作MySQL数据库,下面我将把我自己所理解的笔记整理出来,以作为参考,希望对读者有帮助

为了让读者能够看懂笔者的随笔 我将颜色加深了

简单介绍

  • Python 标准数据库接口为"Python DB-API",而"Python DB-API"为开发人员提供了数据库应用编程接口
  • Python 数据库接口支持非常多的数据库这里举例五种
  1. MySQL
  2. mSQL
  3. PostgreSQL
  4. Microsoft SQL Server
  5. Oracle
  • 如果想要知道更多,可以访问官网Python数据库接口及API查看详细的支持数据库列表
  • 对于不同的数据库需要下载不同的DB API模块,比如需要访问Mysql数据库和Oracle数据库,则需要下载MySQL和Oracle数据库模块
  • Python的DB-API,为多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库
  • Python DB-API操作流程
  1. 导入 DB-API 模块
  2. 获取与数据库的连接
  3. 执行SQL语句和存储过程
  4. 关闭数据库连接

此篇随笔是 Python 操作MySQL数据库,所以需要在操作系统安装MySQLdb模块来支持对Python操作Mysql数据库

MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的


环境准备

  • 首先为了用Python的MySQLdb操作MySQL之前的准备条件

† 必须确保操作系统(Linux CentOS)之上已经已经安装了MySQL数据库

[root@MySQL ~]# rpm -qa | grep mysql                   //查询系统中是否安装Mysql  [root@MySQL ~]# yum -y install mysql mysql-server      //安装Mysql  [root@MySQL ~]# service mysqld start       //启动Mysql  [root@MySQL ~]# chkconfig mysqld on        //设置Mysql开机启动

† 在MySQL数据库上创建数据库 testdb

mysql> show databases;              //显示所有数据库  +--------------------+  | Database           |  +--------------------+  | information_schema |  | mysql              |  | test               |  +--------------------+  3 rows in set (0.00 sec)  mysql> create database testdb;                         //创建testdb数据库  Query OK, 1 row affected (0.00 sec)

† 在testdb数据库中创建数据表 testtab

† testdb表字段里面有 id,name,age,sex

mysql> use testdb;            //进入testdb数据库  Database changed  mysql> create table testtab(                           //创建testtab数据表      -> id int(4),      -> name varchar(255),      -> age int(3),      -> sex varchar(1)      -> );  Query OK, 0 rows affected (0.01 sec)  mysql> desc testtab;           //显示数据表属性  +-------+--------------+------+-----+---------+-------+  | Field | Type         | Null | Key | Default | Extra |  +-------+--------------+------+-----+---------+-------+  | id    | int(4)       | YES  |     | NULL    |       |  | name  | varchar(255) | YES  |     | NULL    |       |  | age   | int(3)       | YES  |     | NULL    |       |  | sex   | varchar(1)   | YES  |     | NULL    |       |  +-------+--------------+------+-----+---------+-------+  4 rows in set (0.00 sec)

† 授权连接数据库testdb使用的用户名为"root" ,密码为 "test123",所有权限

mysql> grant all privileges on testdb.* to 'root'@'%' identified by 'test123' with grant option;  mysql> flush privileges;         //刷新刚才修改的权限,使其生效  Query OK, 0 rows affected (0.00 sec)

† 能连接MySQL保证系统中安装了 Python MySQLdb 模块

† 如果导入MySQLdb的输出结果如下所示,意味着没有安装 MySQLdb 模块

[root@MySQL ~]# python  Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22)  [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2  Type "help", "copyright", "credits" or "license" for more information.  >>> import MySQLdb  Traceback (most recent call last):    File "<stdin>", line 1, in <module>  ImportError: No module named MySQLdb

† 安装MySQLdb,点击进入从这里可选择适合您的平台的安装包,分为预编译的二进制文件和源代码安装包

† 这里使用源码包进行安装,先把依赖包进行安装,不让等下执行安装的时候会出现很多错误...

[root@MySQL ~]# yum install -y python-devel mysql-devel zlib-devel openssl-devel python-setuptools

† 下载MySQL-Python 并解压、安装

[root@MySQL ~]# cd /usr/local/src/  [root@MySQL src]# wget http://download.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.3.tar.gz  [root@MySQL src]# tar zxf MySQL-python-1.2.3.tar.gz  [root@MySQL src]# cd MySQL-python-1.2.3  [root@MySQL MySQL-python-1.2.3]# python setup.py build  [root@MySQL MySQL-python-1.2.3]# python setup.py install

† 如果导入MySQLdb的输出没有任何错误,意味着安装 MySQLdb 模块成功

[root@MySQL ~]# python  Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22)  [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2  Type "help", "copyright", "credits" or "license" for more information.  >>> import MySQLdb  >>>

实例操作[创建、插入]

  • 链接MySQL的testdb数据库并获取一个字段的属性
#!/usr/bin/python  # -*- coding: UTF-8 -*-    #导入MySQLdb模块  import MySQLdb    #打开数据库连接  #host 主机地址、user 用户、passwd 密码 、db 数据库名称、port 数据库端口  conn=MySQLdb.connect(host='192.168.1.187',user='root',passwd='test123',db='testdb',port=3306)    # 使用cursor()方法获取操作游标  cur=conn.cursor()    # 使用execute方法执行SQL语句  cur.execute("describe testtab")    # 使用 fetchone() 方法获取一个字段的属性  data=cur.fetchone()    #打印data这条数据  print data    # 关闭数据库连接  conn.close()

† 执行以上脚本的输出结果

('id', 'int(4)', 'YES', '', None, '')
  • 创建一个VFORBOX数据表
#!/usr/bin/python  # -*- coding: UTF-8 -*-    #导入MySQLdb模块  import MySQLdb    #打开数据库连接  #host 主机地址、user 用户、passwd 密码 、db 数据库名称、port 数据库端口  conn=MySQLdb.connect(host='192.168.1.187',user='root',passwd='test123',db='testdb',port=3306)    # 使用cursor()方法获取操作游标  cur=conn.cursor()    #创建数据库  sql = """CREATE TABLE VFORBOX (           NAME  CHAR(20) NOT NULL,           AGE INT,           SEX CHAR(1))"""    # 使用execute方法执行SQL语句  cur.execute(sql)    # 关闭数据库连接  conn.close()

† 执行以上脚本的输出结果

mysql> use testdb;  Database changed  mysql> show tables;  +------------------+  | Tables_in_testdb |  +------------------+  | VFORBOX          |  | testtab          |  +------------------+  2 rows in set (0.00 sec)  mysql> describe VFORBOX;  +-------+----------+------+-----+---------+-------+  | Field | Type     | Null | Key | Default | Extra |  +-------+----------+------+-----+---------+-------+  | NAME  | char(20) | NO   |     | NULL    |       |  | AGE   | int(11)  | YES  |     | NULL    |       |  | SEX   | char(1)  | YES  |     | NULL    |       |  +-------+----------+------+-----+---------+-------+  3 rows in set (0.00 sec)
  • 执行 SQL INSERT 语句向表 VFORBOX 插入记录
#!/usr/bin/python  # -*- coding: UTF-8 -*-    #导入MySQLdb模块  import MySQLdb    #打开数据库连接  #host 主机地址、user 用户、passwd 密码 、db 数据库名称、port 数据库端口  conn=MySQLdb.connect(host='192.168.1.187',user='root',passwd='test123',db='testdb',port=3306)    # 使用cursor()方法获取操作游标  cur=conn.cursor()    # SQL 插入语句  sql = """INSERT INTO VFORBOX(           NAME, AGE, SEX)           VALUES ('Vforbox', 18, 'M')"""  try:    # 执行sql语句     cur.execute(sql)    # 提交到数据库执行     conn.commit()    except:    # 发生错误时回滚     conn.rollback()    # 关闭数据库连接  conn.close()

† 执行以上脚本的输出结果

mysql> select * from VFORBOX;  +---------+------+------+  | NAME    | AGE  | SEX  |  +---------+------+------+  | Vforbox |   18 | M    |  +---------+------+------+  1 row in set (0.00 sec)
  • 使用变量向SQL语句中传递参数(从以上稍做修改)
#!/usr/bin/python  # -*- coding: UTF-8 -*-    #导入MySQLdb模块  import MySQLdb    #打开数据库连接  #host 主机地址、user 用户、passwd 密码 、db 数据库名称、port 数据库端口  conn=MySQLdb.connect(host='192.168.1.187',user='root',passwd='test123',db='testdb',port=3306)    # 使用cursor()方法获取操作游标  cur=conn.cursor()    # SQL 插入语句  sql = "INSERT INTO VFORBOX( \         NAME, AGE, SEX) \         VALUES ('%s', '%d', '%c')" % \         ('vforbox', 18, 'M')  try:    # 执行sql语句     cur.execute(sql)    # 提交到数据库执行     conn.commit()    except:    # 发生错误时回滚     conn.rollback()    # 关闭数据库连接  conn.close()

† 执行以上脚本的输出结果

mysql> select * from VFORBOX;  +---------+------+------+  | NAME    | AGE  | SEX  |  +---------+------+------+  | Vforbox |   18 | M    |  | Vforbox |   18 | M    |  +---------+------+------+  1 row in set (0.00 sec)

实例操作[查询、更新]

  • Python查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据
  1. fetchone():  方法获取下一个查询结果集,结果集是一个对象
  2. fetchall(): 接收全部的返回结果行
  3. rowcount:  这是一个只读属性,并返回执行execute()方法后影响的行数
  • 查询VFORBOX表中name(姓名)字段等于 vforbox 的所有数据
#!/usr/bin/python  # -*- coding: UTF-8 -*-    #导入MySQLdb模块  import MySQLdb    #打开数据库连接  #host 主机地址、user 用户、passwd 密码 、db 数据库名称、port 数据库端口  conn=MySQLdb.connect(host='192.168.1.187',user='root',passwd='test123',db='testdb',port=3306)    # 使用cursor()方法获取操作游标  cur=conn.cursor()    #SQL查询语句  sql="SELECT * FROM VFORBOX WHERE NAME ='vforbox'"    try:      #执行SQL语句      cur.execute(sql)  #获取所有记录列表      res = cur.fetchall()      for s in res:        name=s[0]        age=s[1]        sex=s[2]  #打印结果输出      print "name=%s,age=%d,sex=%s" % (name,age,sex)  except:      print u"错误:无法行程数据"    # 关闭数据库连接  conn.close()

† 执行以上脚本的输出结果

name=vforbox,age=20,sex=M
  • 更新操作用于更新数据表的的数据,将 VFORBOX表中的 SEX 字段全部修改为 'M',AGE 字段递增1
#!/usr/bin/python  # -*- coding: UTF-8 -*-    #导入MySQLdb模块  import MySQLdb    #打开数据库连接  #host 主机地址、user 用户、passwd 密码 、db 数据库名称、port 数据库端口  conn=MySQLdb.connect(host='192.168.1.187',user='root',passwd='test123',db='testdb',port=3306)    # 使用cursor()方法获取操作游标  cur=conn.cursor()    #SQL更新语句  sql = "UPDATE VFORBOX SET AGE = AGE + 1 WHERE SEX = 'M'"  try:      #执行SQL语句      cur.execute(sql)      #提交到数据库执行      conn=commit()  except:      conn.rollback()  # 关闭数据库连接  conn.close()

† 执行以上脚本的输出结果

mysql> select * from VFORBOX;  +---------+------+------+  | NAME    | AGE  | SEX  |  +---------+------+------+  | vforbox |   21 | M    |  +---------+------+------+  1 rows in set (0.00 sec)

DB-API错误处理

异常 描述
Warning 当有严重警告时触发,例如插入数据是被截断等等,必须是 StandardError 的子类
Error 警告以外所有其他错误类,必须是 StandardError 的子类
InterfaceError 当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发,必须是Error的子类
DatabaseError 和数据库有关的错误发生时触发, 必须是Error的子类
DataError 当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等,必须是DatabaseError的子类
OperationalError

指非用户控制的,而是操作数据库时发生的错误

例如:连接意外断开、数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误, 必须是DatabaseError的子类

IntegrityError 完整性相关的错误,例如外键检查失败等,必须是DatabaseError子类
InternalError 数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等. 必须是DatabaseError子类
ProgrammingError 程序错误,例如数据表(table)没找到或已存在、SQL语句语法错误、 参数数量错误等等,必须是DatabaseError的子类
NotSupportedError

不支持错误,指使用了数据库不支持的函数或API等

例如在连接对象上 使用.rollback()函数,然而数据库并不支持事务或者事务已关闭,必须是DatabaseError的子类

</div>
</div> </div> </div> </div> </div> </div> </div> </div>
来自:http://www.cnblogs.com/vforbox/p/4831695.html