详细介绍Python 操作MySQL数据库
为了让读者能够看懂笔者的随笔 我将颜色加深了
简单介绍
- Python 标准数据库接口为"Python DB-API",而"Python DB-API"为开发人员提供了数据库应用编程接口
- Python 数据库接口支持非常多的数据库这里举例五种
- MySQL
- mSQL
- PostgreSQL
- Microsoft SQL Server
- Oracle
- 如果想要知道更多,可以访问官网Python数据库接口及API查看详细的支持数据库列表
- 对于不同的数据库需要下载不同的DB API模块,比如需要访问Mysql数据库和Oracle数据库,则需要下载MySQL和Oracle数据库模块
- Python的DB-API,为多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库
- Python DB-API操作流程
- 导入 DB-API 模块
- 获取与数据库的连接
- 执行SQL语句和存储过程
- 关闭数据库连接
此篇随笔是 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 >>>
实例操作[创建、插入]
#!/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, '')
#!/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)
#!/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)
#!/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() 方法获取多条数据
- fetchone(): 方法获取下一个查询结果集,结果集是一个对象
- fetchall(): 接收全部的返回结果行
- rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数
#!/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
#!/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的子类 |
来自:http://www.cnblogs.com/vforbox/p/4831695.html