MySQL适配器 / MySQL Adapter


MySQL是一种关系型数据库,下面主要介绍利用如何利用Python的MySQL适配器来对MySQL进行操作,其余内容可参考文末相关阅读

1 MySQL环境配置 / Environment Configuration

安装MySQL

首先在官网下载对应版本的MySQL,在安装过程中会要求Visual Studio 201x的安装环境,可前往下载Visual Studio 2015版本,安装完毕后重启完成MySQL安装。

配置MySQL

  1. 在安装目录下找到配置文件,my-default.ini,重命名为my.ini;
  2. 在环境变量中添加MySQL路径(eg.:C:\Program Files\MySQL\MySQL Server 5.7\bin);
  3. 安装MySQL服务,管理员模式打开cmd,执行命令mysqld –install MySQL –defaults-file=”my.ini”,看到提示Service Successfully installed表示安装成功。

Note: 可使用bat完成第3步操作

mysqld --install MySQL --defaults-file="my.ini"  

MySQL服务的启动、停止和卸载

在cmd下运行:

启动: net start MySQL

停止: net stop MySQL

卸载: sc delete MySQL

MySQL登录

直接操作MySQL,无需适配器,

cmd登录本地MySQL: MySQL -u username -p[ db_name] (then input your password)

2 MySQLdb适配器 / MySQLdb Adaptor

以MySQLdb适配器为例,连接MySQL数据库。

2.1 安装MySQLdb / Install MySQLdb

安装Python对MySQL的适配器,可使用pip进行安装,Python 2可安装MySQL-python,而对于Python 3需安装mysqlclient。

pip install mysqlclient  

2.2 DB-API扩展 / DB-API Extension

这部分内容为在通用标准基础上额外扩展的 API 接口。

2.2.1 query()方法

函数调用: cnx.query(sql)

函数功能:发送SQL语句进行执行

传入参数: sql

sql: str类型,需要执行的SQL语句

返回参数:

2.2.2 store_result ()方法

函数调用: rst = cnx.store_result()

函数功能:一般在query()发送SQL的请求命令之后,用于保存返回信息

传入参数:

返回参数: rst

rst: obj类型,一个数据结果对象

2.2.3 fetch_row ()方法

函数调用: r = rst.fetch_row(size, type=0)

函数功能:用于从保存的返回信息中获取结果

传入参数: size, type

size: int类型,获取数据数量,0则获取所有数据

type: int类型,0则返回的每条结果为元组,标准DB规定,1为字典,2为老式字典形式,不推荐使用

返回参数: r

r: tuple类型,包含获取的结果信息

3 适配器构建示例 / Adaptor Build Example

下面的例子将以MySQL的操作语句为例,构建一个适用于MySQL数据库的适配器,以root权限登录并进行一系列操作。

 class SqlConnector():
def __init__(self, adaptor):
self.adaptor = adaptor
self.result = None
# Check Adaptor info
print('Adaptor %s apply DB-API %s, thread safety: %d, parameter style: %s' % (adaptor.__name__, adaptor.apilevel, adaptor.threadsafety, adaptor.paramstyle)) # Login by user name and password
def login(self, host='localhost', user='root', password='root', **kwargs):
# Create a connection obj
self.cnx = self.adaptor.connect(host=host, user=user, password=password, **kwargs) def logoff(self):
self.cnx.close() def query_sql(self, sql, show=True):
# Method one: Use Connection
'''
self.cnx.query(sql)
self.result = self.cnx.store_result()
self.cnx.commit()
r = self.result.fetch_row(0, )
'''
# Method two: Use Cursor
cur = self.cnx.cursor()
cur.execute(sql)
self.cnx.commit()
r = cur.fetchall()
cur.close() if show:
splt = '\n' + ((len(sql)+6)*'-')
msg = ''.join(('\n{: ^10} | ').format(str(i)) if x.index(i) == 0 else ('{: ^10} | ').format(str(i)) for x in r for i in x)
s = ('{:-^%d}'%(len(sql)+6)).format(sql) + msg + splt
print(s)
return (i for x in r for i in x) def exec_sql(self, sql):
cur = self.cnx.cursor()
cur.execute(sql)
self.cnx.commit()
cur.close() def create_try(self, sql_create, sql_drop, name):
try:
self.exec_sql(sql_create)
print('%s create success' % name)
# MySQLdb.ProgrammingError or MySQLdb.OperationalError
except:
r = input('%s may exist, delete and create a new one?[y/n]' % name)
if r == 'n':
print('Failed to create %s' % name)
return False
try:
self.exec_sql(sql_drop)
print('%s delete success' % name)
self.exec_sql(sql_create)
print('%s create success' % name)
except:
print('Failed to create %s' % name)
return False
return True # --------------- For user handle -------------------
def create_user(self, usn, psw):
sql = 'CREATE USER %s IDENTIFIED BY "%s";' % (usn, psw)
try:
self.exec_sql(sql)
except MySQLdb.OperationalError:
print('Create user %s failed' % usn)
return False
return True def show_grants(self, usn):
sql = 'SHOW GRANTS FOR %s;' % usn
# re = self.query_sql(sql)
self.query_sql(sql) def grant_for(self, user):
pass # --------------- For database handle -------------------
def create_database(self, db_name):
# Try to CREATE a database, DELETE database if create failed
# And try CREATE again, if failed again, exit
# You can try 'CREATE DATABASE IF NOT EXISTS db_name;' too
sql_create = 'CREATE DATABASE %s;' % db_name
sql_drop = 'DROP DATABASE %s;' % db_name
return self.create_try(sql_create, sql_drop, db_name) def drop_database(self, db_name):
sql = 'DROP DATABASE IF EXISTS %s;' % db_name
self.exec_sql(sql) def use_database(self, db_name):
sql = 'USE %s;' % db_name
self.exec_sql(sql) def show_databases(self):
sql = 'SHOW DATABASES;'
re = self.query_sql(sql)
# print(list(re)) # --------------- For table handle -------------------
def create_table(self, tb_name, tb_info, db_name=None):
if db_name:
self.use_database(db_name)
tb_info = (', '.join('%s %s' % (k, v) for k, v in tb_info.items())).join('()')
sql_create = 'CREATE TABLE %s %s;' % (tb_name, tb_info)
sql_drop = 'DROP TABLE %s;' % tb_name
return self.create_try(sql_create, sql_drop, tb_name) def drop_table(self, tb_name, db_name=None):
if db_name:
self.use_database(db_name)
sql = 'DROP TABLE IF EXISTS %s;' % tb_name
self.exec_sql(sql) #def use_table(self, tb_name, db_name=None):
# if db_name:
# self.use_database(db_name)
# sql = 'USE %s;' % tb_name
# self.exec_sql(sql) def show_tables(self, db_name):
self.use_database(db_name)
sql = 'SHOW TABLES;'
self.query_sql(sql) def describe_table(self, tb_name, db_name=None):
if db_name:
self.use_database(db_name)
sql = 'DESCRIBE %s;' % tb_name
self.query_sql(sql) # --------------- For column handle -------------------
def insert_column(self, tb_name, value):
sql = 'INSERT INTO %s VALUES %s' % (tb_name, value)
self.query_sql(sql) def drop_columns(self, tb_name, cl_name, value):
if isinstance(value, str):
value = value.join("''")
sql = "DELETE FROM %s WHERE %s=%s" % (tb_name, cl_name, str(value))
self.query_sql(sql, show=False) def insert_columns(self, tb_name, values):
n = len(values[0])
qn = (', '.join('%s' for x in range(n))).join('()')
sql = 'INSERT INTO %s VALUES%s' % (tb_name, qn)
print(sql)
cur = self.cnx.cursor()
cur.executemany(sql, values)
cur.close() def show_columns(self, tb_name):
sql = 'SHOW COLUMNS in %s;' % tb_name
self.query_sql(sql) def show_all_rows(self, tb_name):
sql = 'SELECT * FROM %s' % tb_name
self.query_sql(sql) def select_row(self, tb_name, cl_name):
row_name = ', '.join(x for x in cl_name)
sql = 'SELECT %s FROM %s' % (row_name, tb_name)
self.query_sql(sql) if __name__ == '__main__':
import MySQLdb
c = SqlConnector(MySQLdb)
#c = SqlConnector(pyodbc)
c.login()
c.create_database('mysql_db')
c.use_database('mysql_db')
#c.create_user('Ericsson', '123456')
#c.show_grants('Ericsson')
#c.show_databases()
#c.drop_database('test_db')
c.show_databases()
from collections import OrderedDict
ord_dict = OrderedDict()
ord_dict['id'] = 'TINYINT'
ord_dict['name'] = 'VARCHAR(8)'
ord_dict['age'] = 'INT'
c.create_table('test_tb', ord_dict, db_name='mysql_db')
c.show_tables('mysql_db')
c.describe_table('test_tb')
c.show_all_rows('test_tb')
c.insert_column('test_tb', (7, 'ANAY', 9))
c.insert_columns('test_tb', [(4, 'AX', 2), (5, 'SD', 2), (6, 'CSA', 5)])
c.drop_columns('test_tb', 'name', '')
c.show_all_rows('test_tb')
c.show_columns('test_tb')
#c.select_row('test_tb', ('age', 'name'))
c.logoff()

首先建立适配器,适配器可以使用继承通用适配器中应用示例的适配器进行构建,以减少代码重复。此处未采用继承,直接进行建立。

第 1-42 行,定义适配器类的基本操作方法。

第 44-62 行,定义一个创建尝试函数,当有需要创建一个新的数据库或表格时,会进行一个创建尝试,若创建失败,则可能是由于创建对象已存在导致的,询问用户是否尝试删除原表,若是则尝试删除后再次重建。

第 64-80 行,定义用于用户管理的函数,如创建用户,查看用户权限等(其余待补充)。

第 82-102 行,定义用于创建、删除、使用及显示数据库的函数。

第 104-134行,定义用于创建、删除、显示表的函数。

第 136-167 行,定义用于插入(多)、删除、显示列的函数,以及显示表内数据的函数。

第 171-181 行,执行函数,首先创建表,并选择使用创建的表,

第 182-183 行,此处由于字典的无序性,会导致列顺序无法确定,因此引入了有序字典。

第 184-197 行,对表进行一系列操作,并最终退出登录。

最终输出结果如下,

Adaptor MySQLdb apply DB-API 2.0, thread safety: 1, parameter style: format
mysql_db may exist, delete and create a new one?[y/n]y
mysql_db delete success
mysql_db create success
---SHOW DATABASES;---
information_schema |
my_database |
my_schema |
mysql |
mysql_db |
performance_schema |
sakila |
sys |
test_db |
world |
---------------------
test_tb create success
---SHOW TABLES;---
test_tb |
------------------
---DESCRIBE test_tb;---
id | tinyint(4) | YES | | None | |
name | varchar(8) | YES | | None | |
age | int(11) | YES | | None | |
-----------------------
---SELECT * FROM test_tb---
---------------------------
---INSERT INTO test_tb VALUES (7, 'ANAY', 9)---
-----------------------------------------------
INSERT INTO test_tb VALUES(%s, %s, %s)
---SELECT * FROM test_tb---
7 | ANAY | 9 |
4 | AX | 2 |
5 | SD | 2 |
6 | CSA | 5 |
---------------------------
---SHOW COLUMNS in test_tb;---
id | tinyint(4) | YES | | None | |
name | varchar(8) | YES | | None | |
age | int(11) | YES | | None | |
------------------------------

至此,利用 Python 完成了一个简单的数据库适配器。

相关阅读


1. 数据库概述

2. DB-API 通用标准

参考链接


http://www.cnblogs.com/mr-wid/archive/2013/05/09/3068229.html

http://jingyan.baidu.com/article/414eccf612e0c16b431f0a95.html

Python与数据库[1] -> 数据库接口/DB-API[1] -> MySQL 适配器的更多相关文章

  1. Python与数据库[1] -> 数据库接口/DB-API[2] -> SQL Server 适配器

    SQL_Server适配器 / SQL_Server Adapter 1 环境配置 / Environment Configuration 安装SQL_Server的Python适配器包 pip in ...

  2. Python进阶----数据库引擎(InnoDB),表的创建,mysql的数据类型,mysql表的约束

    Python进阶----数据库引擎(InnoDB),表的创建,mysql的数据类型,mysql表的约束 一丶MySQL的存储引擎 什么是存储引擎:    MySQL中的数据用各种不同的技术存储在文件( ...

  3. Python与数据库[1] -> 数据库接口/DB-API[0] -> 通用标准

    数据库接口 / DB-API 在Python中,数据库是通过适配器(Adaptor)来连接访问数据库的,适配器通常与数据库客户端接口(通常为C语言编写)想连接,而不同的适配器都会尽量满足相同的DB-A ...

  4. Python与数据库[1] -> 数据库接口/DB-API[3] -> ODBC 适配器

    ODBC适配器 / ODBC Adaptor ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Service ...

  5. Python与数据库

    链接汇总 https://www.cnblogs.com/stacklike/category/1134822.html Python与数据库[1] -> 数据库接口/DB-API[0] -&g ...

  6. Atitit.跨语言数据库db  api兼容性 jdbc odbc ado oledb 增强方案

    Atitit.跨语言数据库db  api兼容性 jdbc odbc ado oledb 增强方案 1. 跨语言db api兼容性..1 2. 目前访问数据库的接口很多.比较常用的jdbc odbc 以 ...

  7. Python DB API 连接数据库

    Python DB API Mysql,Oracle,SqlServer 不关闭,会浪费资源.

  8. 零基础学Python--------第11章 使用Python操作数据库

    第11章 使用Python操作数据库 11.1 数据库编程接口 在项目开发中,数据库应用必不可少.虽然数据库的种类有很多,如SQLite.MySQL.Oracle等,但是它们的功能基本都是一样的,为了 ...

  9. python操作数据库(Mysql)

    原文地址:https://www.cnblogs.com/R-bear/p/7022231.html python DB-API介绍 1.python标准数据库接口为 python DB-API,py ...

随机推荐

  1. .swp文件的恢复

    .swp 编辑文件的过程中会出现这个隐藏文件. 文件如果正常保存,.swp就会自动删除.如果不正常退出,比如关机,.swp就会留下来. linux下: ls -all 可以查看隐藏文件 命令: vi ...

  2. badboy录制提示当前页面的脚本发生错误

    利用badboy录制时,发生了错误: 网上查了查,说badboy默认使用IE浏览器,打开Internet选项—>高级,图中的两个选项不要勾选即可 然鹅,然鹅,并没有作用... 请教了好心的同行, ...

  3. uiautomator+cucumber实现移动app自动化测试

    前提 由于公司业务要求,所以自动化测试要达到以下几点: 跨应用的测试 测试用例可读性强 测试报告可读性强 对失败的用例有截图保存并在报告中体现 基于以上几点,在对自动化测试框架选型的时候就选择了uia ...

  4. Python网络编程(OSI模型、网络协议、TCP)

    前言: 什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系. 在数学上,网络是一种图,一般认为专指加权图. 网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类 型的实际问题中抽象 ...

  5. Eureka 使用Spring cloud config 管理中心启动

    Config 工程创建之后,Eureka就可以使用Git上的配置启动服务了. Git 服务器的搭建这里就不细说了(自行解决),下面是我上传再git的配置文件: 创建EurekaServer项目(eur ...

  6. android桌面悬浮窗实现

                            首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. ...

  7. reinterpret_cast and const_cast

    reinterpret_cast reinterpret意为“重新解释” reinterpret_cast是C++中与C风格类型转换最接近的类型转换运算符.它让程序员能够将一种对象类型转换为另一种,不 ...

  8. URAL 1934 spfa算法

    D - Black Spot Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Subm ...

  9. 01、JAVA开发准备

    一.首先要认识几个名词: 1. JRE(Java Runtime Environment ,JAVA运行环境):它包含Java虚拟机(JVM,Java Virtual Machine)和Java程序所 ...

  10. Visual Studio 2017 添加引用报错(未能正确加载ReferenceManagerPackage包)

    最近安装了VS2017,在开发时需要添加引用,于是像原来使用vs2012那样直接右键,添加引用,结果弹出一个错误提示“未能完成操作.不支持此接口”.真真是见了鬼了...... google.度娘一顿搜 ...