MySQLdb:Python 操作 MySQL 数据库
admin
2023-07-31 01:44:52
0

环境:MySQL 5.6.27, Ubuntu 15.10 64-bit

个人笔记,可读性较差。寻教程请移步:MySQL Python tutorial

官方简介

MySQLdb is an thread-compatible interface to the popular MySQL
database server that provides the Python database API.

安装

通过 pip 安装

$ apt-get install python-dev libmysqlclient-dev
$ pip install MySQL-python

详见:How to install Python MySQLdb module using pip?

通过 apt 安装

$ sudo apt-get install python-mysqldb

模块 _mysql

MySQLdb 安装好后,有两个模块或方式可用。模块 _mysql 提供的是类似于 MySQL C 接口的 API,而模块 MySQLdb_mysql 基础上又做了进一步封装,使之符合 Python 的数据库 API 规范。推荐使用后者。

使用 _mysql 的例子:

import _mysql
import sys

try:
    con = _mysql.connect(\'localhost\', \'root\', \'******\', \'test\')

    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()

改用 MySQLdb

import MySQLdb as mdb
import sys

try:
    con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

    cur = con.cursor()
    cur.execute(\'select version()\')

    ver = cur.fetchone()

    print \'MySQL 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()

创建表,插入数据

# coding: utf-8

import MySQLdb as mdb

con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

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)) default charset utf8\')
    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\")\')
    cur.execute(\'insert into writers(name) values(\"曹雪芹\")\')

查询

一次取回所有结果:fetchall

import MySQLdb as mdb

con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

with con:
    cur = con.cursor()
    cur.execute(\'select * from writers\')

    # 结果集 rows 为元组(tuple)的元组,每一个元组代表了表中的一行。
    rows = cur.fetchall()
    for row in rows:
        print row

挨个取回结果:fetchone

import MySQLdb as mdb

con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

with con:
    cur = con.cursor()
    cur.execute(\'select * from writers\')

    for i in range(cur.rowcount):
        row = cur.fetchone()
        print row

使用字典 Cursor

import MySQLdb as mdb

con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

def test_dict_cursor():
    with con:
        cur = con.cursor(mdb.cursors.DictCursor) # 字典 cursor
        cur.execute(\'select * from writers limit 4\')

        # rows 为字典的元组
        rows = cur.fetchall()
        for row in rows:
            print row[\'id\'], row[\'name\'] # 通过列名访问结果

打印列名

import MySQLdb as mdb

con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

with con:
    cur = con.cursor()
    cur.execute(\'select * from writers limit 4\')

    rows = cur.fetchall()
        
    # 元组的元组,每一个元组对应一个结果列,元组的第一个元素为列名。
    desc = cur.description

    # 打印前两个结果列的列名。
    print \'%s %3s\' % (desc[0][0], desc[1][0])

    for row in rows:
        print \'%2s %3s\' % row

Prepared Statements

Prepared Statements 可以提高安全性和性能,特别是对于多次重复执行的查询。Python 的数据库 API 规范建议了 5 种不同的方式来构造 Prepared Statements,MySQLdb 只支持其中的一种,代码类似于 ANSI printf 的格式化操作。

Prepared Statements 在 ORM 库(比如 SQLAlchemy)中应该会有更完善的支持。

注(2016-01-10):
这里的 Prepared Statements 只是客户端的模拟,跟 MySQL Server 的 Prepared Statements 是两码事,所以并不能提高性能或安全性。(详见 C API Prepared Statements)

import MySQLdb as mdb

con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

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

事务

前面的例子一直使用 with 语句来管理链接 (connection) 对象,避免了 commit 的直接调用。

一旦 cursor 创建,一个事务也就开始,结束时必须调用 commitrollbackcommit 提交修改,rollback 回滚。如果结合 with 语句使用的话,commitrollback 都将自动完成,因为 MySQLdb 的链接对象可以当作 context manager 使用。

# coding: utf-8

import MySQLdb as mdb

try:
    con = mdb.connect(\'localhost\', \'root\', \'******\', \'test\')

    # Cursor 创建,事务开始。
    cur = con.cursor()

    cur.execute(\'drop table if exists writers\')
    # MyISAM doesn\'t support transaction.
    cur.execute(\'create table writers(id int primary key auto_increment,\\
            name varchar(25)) engine=innodb\')

    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\")\')

    # 显式地调用 commit 来结束一个事务。
    con.commit()

except mdb.Error, e:
    # 异常发生时,调用 rollback 进行回滚。
    if con:
        con.rollback()

    print \"Error %d: %s\" % (e.args[0], e.args[1])
    sys.exit(1)

finally:
    if con:
        con.close()

Cursor 有必要 close 吗?

原则上讲,不需要显式地调用 cursor 对象的 close 方法,因为当 cursor 对象生命期结束时,close 方法会被自动调用。源码如下:

class BaseCursor(object):
    def __del__(self):
        self.close()
        self.errorhandler = None
        self._result = None

不过,还是建议主动调用 close,这样至少代码的行为更加明显。

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...