MySQL Connector / Python允许Python程序使用符合Python数据库API规范v2.0(PEP 249)的API访问MySQL数据库 。
MySQL Connector / Python包括对以下内容的支持:
几乎所有MySQL Server提供的功能都包括MySQL Server版本5.7。
Connector / Python 8.0也支持X DevAPI。有关使用X DevAPI的MySQL Connector / Python的概念和用法的文档,请参阅 X DevAPI用户指南。
在Python和MySQL数据类型之间来回转换参数值,例如Python datetime 和MySQL DATETIME。为方便起见,您可以打开自动转换,或者关闭以获得最佳性能。
标准SQL语法的所有MySQL扩展。
协议压缩,可以压缩客户端和服务器之间的数据流。
使用TCP / IP套接字的连接和使用Unix套接字的Unix连接。
使用SSL保护TCP / IP连接。
独立的驱动。Connector / Python不需要MySQL客户端库或标准库之外的任何Python模块。
1使用Connector / Python连接MySQL
该connect()构造函数创建到MySQL服务器的连接并返回一个 MySQLConnection对象。
以下示例显示如何连接到MySQL服务器:
import mysql.connector
cnx = mysql.connector.connect(user='scott', password='password',
host='127.0.0.1',
database='employees')
cnx.close()
也可以使用connection.MySQLConnection() 类创建连接对象 :
from mysql.connector import (connection)
cnx = connection.MySQLConnection(user='scott', password='password',
host='127.0.0.1',
database='employees')
cnx.close()
两种形式(使用connect() 构造函数或直接使用类)都是有效且功能相同的,但是connect()本手册中的大多数示例都是首选使用的。
要处理连接错误,请使用该try 语句并使用errors.Error 异常捕获所有错误 :
import mysql.connector
from mysql.connector import errorcode
try:
cnx = mysql.connector.connect(user='scott',
database='employ')
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("Something is wrong with your user name or password")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("Database does not exist")
else:
print(err)
else:
cnx.close()
在字典中定义连接参数并使用 **运算符是另一种选择:
import mysql.connector
config = {
'user': 'scott',
'password': 'password',
'host': '127.0.0.1',
'database': 'employees',
'raise_on_warnings': True
}
cnx = mysql.connector.connect(**config)
cnx.close()
2使用Connector / Python创建表
所有DDL(数据定义语言)语句都使用称为游标的句柄结构执行。以下示例显示如何创建Employee示例数据库的表 。你需要它们用于其他例子。
在MySQL服务器中,表是非常长寿的对象,并且通常由以不同语言编写的多个应用程序访问。您通常可以使用已设置的表,而不是在自己的应用程序中创建它们。避免一遍又一遍地设置和丢弃表,因为这是一项昂贵的操作。临时表是一个例外 ,可以在应用程序中快速创建和删除。
from __future__ import print_function
import mysql.connector
from mysql.connector import errorcode
DB_NAME = 'employees'
TABLES = {}
TABLES['employees'] = (
"CREATE TABLE `employees` ("
" `emp_no` int(11) NOT NULL AUTO_INCREMENT,"
" `birth_date` date NOT NULL,"
" `first_name` varchar(14) NOT NULL,"
" `last_name` varchar(16) NOT NULL,"
" `gender` enum('M','F') NOT NULL,"
" `hire_date` date NOT NULL,"
" PRIMARY KEY (`emp_no`)"
") ENGINE=InnoDB")
TABLES['departments'] = (
"CREATE TABLE `departments` ("
" `dept_no` char(4) NOT NULL,"
" `dept_name` varchar(40) NOT NULL,"
" PRIMARY KEY (`dept_no`), UNIQUE KEY `dept_name` (`dept_name`)"
") ENGINE=InnoDB")
TABLES['salaries'] = (
"CREATE TABLE `salaries` ("
" `emp_no` int(11) NOT NULL,"
" `salary` int(11) NOT NULL,"
" `from_date` date NOT NULL,"
" `to_date` date NOT NULL,"
" PRIMARY KEY (`emp_no`,`from_date`), KEY `emp_no` (`emp_no`),"
" CONSTRAINT `salaries_ibfk_1` FOREIGN KEY (`emp_no`) "
" REFERENCES `employees` (`emp_no`) ON DELETE CASCADE"
") ENGINE=InnoDB")
TABLES['dept_emp'] = (
"CREATE TABLE `dept_emp` ("
" `emp_no` int(11) NOT NULL,"
" `dept_no` char(4) NOT NULL,"
" `from_date` date NOT NULL,"
" `to_date` date NOT NULL,"
" PRIMARY KEY (`emp_no`,`dept_no`), KEY `emp_no` (`emp_no`),"
" KEY `dept_no` (`dept_no`),"
" CONSTRAINT `dept_emp_ibfk_1` FOREIGN KEY (`emp_no`) "
" REFERENCES `employees` (`emp_no`) ON DELETE CASCADE,"
" CONSTRAINT `dept_emp_ibfk_2` FOREIGN KEY (`dept_no`) "
" REFERENCES `departments` (`dept_no`) ON DELETE CASCADE"
") ENGINE=InnoDB")
TABLES['dept_manager'] = (
" CREATE TABLE `dept_manager` ("
" `dept_no` char(4) NOT NULL,"
" `emp_no` int(11) NOT NULL,"
" `from_date` date NOT NULL,"
" `to_date` date NOT NULL,"
" PRIMARY KEY (`emp_no`,`dept_no`),"
" KEY `emp_no` (`emp_no`),"
" KEY `dept_no` (`dept_no`),"
" CONSTRAINT `dept_manager_ibfk_1` FOREIGN KEY (`emp_no`) "
" REFERENCES `employees` (`emp_no`) ON DELETE CASCADE,"
" CONSTRAINT `dept_manager_ibfk_2` FOREIGN KEY (`dept_no`) "
" REFERENCES `departments` (`dept_no`) ON DELETE CASCADE"
") ENGINE=InnoDB")
TABLES['titles'] = (
"CREATE TABLE `titles` ("
" `emp_no` int(11) NOT NULL,"
" `title` varchar(50) NOT NULL,"
" `from_date` date NOT NULL,"
" `to_date` date DEFAULT NULL,"
" PRIMARY KEY (`emp_no`,`title`,`from_date`), KEY `emp_no` (`emp_no`),"
" CONSTRAINT `titles_ibfk_1` FOREIGN KEY (`emp_no`)"
" REFERENCES `employees` (`emp_no`) ON DELETE CASCADE"
") ENGINE=InnoDB")
上面的代码显示了我们如何将CREATE语句存储在 名为的Python字典中 TABLES。我们还在一个名为的全局变量中定义数据库DB_NAME,这使您可以轻松使用不同的模式。
cnx = mysql.connector.connect(user='scott')
cursor = cnx.cursor()
单个MySQL服务器可以管理多个 数据库。通常,您指定要在连接到MySQL服务器时切换到的数据库。此示例在连接时不连接到数据库,因此它可以确保数据库存在,如果不存在则创建它:
def create_database(cursor):
try:
cursor.execute(
"CREATE DATABASE {} DEFAULT CHARACTER SET 'utf8'".format(DB_NAME))
except mysql.connector.Error as err:
print("Failed creating database: {}".format(err))
exit(1)
try:
cursor.execute("USE {}".format(DB_NAME))
except mysql.connector.Error as err:
print("Database {} does not exists.".format(DB_NAME))
if err.errno == errorcode.ER_BAD_DB_ERROR:
create_database(cursor)
print("Database {} created successfully.".format(DB_NAME))
cnx.database = DB_NAME
else:
print(err)
exit(1)
我们首先尝试使用database连接对象的属性 更改为特定数据库 cnx。如果有错误,我们检查错误号以检查数据库是否不存在。如果是这样,我们调用 create_database函数为我们创建它。
在任何其他错误上,应用程序退出并显示错误消息。
在我们成功创建或更改目标数据库之后,我们通过迭代TABLES字典的项来创建表 :
for table_name in TABLES:
table_description = TABLES[table_name]
try:
print("Creating table {}: ".format(table_name), end='')
cursor.execute(table_description)
except mysql.connector.Error as err:
if err.errno == errorcode.ER_TABLE_EXISTS_ERROR:
print("already exists.")
else:
print(err.msg)
else:
print("OK")
cursor.close()
cnx.close()
要在表已存在时处理错误,我们会通知用户它已经存在。打印其他错误,但我们继续创建表。(该示例显示了如何处理 “ 表已存在 ”条件以用于说明目的。在实际应用程序中,我们通常通过使用语句的IF NOT EXISTS子句完全避免错误条件CREATE TABLE。)
输出将是这样的:
Database employees does not exists.
Database employees created successfully.
Creating table employees: OK
Creating table departments: already exists.
Creating table salaries: already exists.
Creating table dept_emp: OK
Creating table dept_manager: OK
Creating table titles: OK
要填充employees表,请使用Employee Sample Database的转储文件 。请注意,您只需要在名为的存档中找到的数据转储文件 employees_db-dump-files-1.0.5.tar.bz2。下载转储文件后,执行以下命令,必要时向mysql命令添加连接选项:
shell> tar xzf employees_db-dump-files-1.0.5.tar.bz2
shell> cd employees_db
shell> mysql employees < load_employees.dump
shell> mysql employees < load_titles.dump
shell> mysql employees < load_departments.dump
shell> mysql employees < load_salaries.dump
shell> mysql employees < load_dept_emp.dump
shell> mysql employees < load_dept_manager.dump
3使用Connector / Python插入数据
使用称为游标的处理程序结构也可以完成插入或更新数据。当您使用事务性存储引擎,如InnoDB(在MySQL 5.5和更高的默认设置),则必须提交 的序列后的数据 INSERT, DELETE以及 UPDATE报表。
此示例显示如何插入新数据。第二个 INSERT取决于第一个新创建的主键的值 。该示例还演示了如何使用扩展格式。任务是添加一名新员工,明天开始工作,薪水设置为50000。
注意
以下示例使用示例 “使用Connector / Python创建表”中创建的表。表AUTO_INCREMENT的主键的 列选项对于employees确保可靠,易于搜索的数据非常重要。
from __future__ import print_function
from datetime import date, datetime, timedelta
import mysql.connector
cnx = mysql.connector.connect(user='scott', database='employees')
cursor = cnx.cursor()
tomorrow = datetime.now().date() + timedelta(days=1)
add_employee = ("INSERT INTO employees "
"(first_name, last_name, hire_date, gender, birth_date) "
"VALUES (%s, %s, %s, %s, %s)")
add_salary = ("INSERT INTO salaries "
"(emp_no, salary, from_date, to_date) "
"VALUES (%(emp_no)s, %(salary)s, %(from_date)s, %(to_date)s)")
data_employee = ('Geert', 'Vanderkelen', tomorrow, 'M', date(1977, 6, 14))
# Insert new employee
cursor.execute(add_employee, data_employee)
emp_no = cursor.lastrowid
# Insert salary information
data_salary = {
'emp_no': emp_no,
'salary': 50000,
'from_date': tomorrow,
'to_date': date(9999, 1, 1),
}
cursor.execute(add_salary, data_salary)
# Make sure data is committed to the database
cnx.commit()
cursor.close()
cnx.close()
我们首先打开与MySQL服务器的连接,并将连接对象存储 在变量中cnx。然后 ,我们使用连接的 方法创建一个新的游标,默认情况下是一个 MySQLCursor对象 cursor()。
4使用Connector / Python查询数据
以下示例说明如何使用使用连接 方法创建的游标来 查询数据 cursor()。返回的数据被格式化并打印在控制台上。
任务是选择1999年雇用的所有员工,并将他们的姓名和雇用日期打印到控制台。
import datetime
import mysql.connector
cnx = mysql.connector.connect(user='scott', database='employees')
cursor = cnx.cursor()
query = ("SELECT first_name, last_name, hire_date FROM employees "
"WHERE hire_date BETWEEN %s AND %s")
hire_start = datetime.date(1999, 1, 1)
hire_end = datetime.date(1999, 12, 31)
cursor.execute(query, (hire_start, hire_end))
for (first_name, last_name, hire_date) in cursor:
print("{}, {} was hired on {:%d %b %Y}".format(
last_name, first_name, hire_date))
cursor.close()
cnx.close()
我们首先打开与MySQL服务器的连接,并将连接对象存储 在变量中cnx。然后 ,我们使用连接的 方法创建一个新的游标,默认情况下是一个 MySQLCursor对象 cursor()。
5以下示例脚本明天向所有加入2000年且仍在公司的员工提交了15%的提前生效。
为了遍历选定的员工,我们使用缓冲游标。(缓冲的游标在执行查询后获取并缓冲结果集的行;请参见 第10.6.1节“cursor.MySQLCursorBuffered类”。)这样,就不必获取新变量中的行。相反,游标可以用作迭代器。
from __future__ import print_function
from decimal import Decimal
from datetime import datetime, date, timedelta
import mysql.connector
# Connect with the MySQL Server
cnx = mysql.connector.connect(user='scott', database='employees')
# Get two buffered cursors
curA = cnx.cursor(buffered=True)
curB = cnx.cursor(buffered=True)
# Query to get employees who joined in a period defined by two dates
query = (
"SELECT s.emp_no, salary, from_date, to_date FROM employees AS e "
"LEFT JOIN salaries AS s USING (emp_no) "
"WHERE to_date = DATE('9999-01-01')"
"AND e.hire_date BETWEEN DATE(%s) AND DATE(%s)")
# UPDATE and INSERT statements for the old and new salary
update_old_salary = (
"UPDATE salaries SET to_date = %s "
"WHERE emp_no = %s AND from_date = %s")
insert_new_salary = (
"INSERT INTO salaries (emp_no, from_date, to_date, salary) "
"VALUES (%s, %s, %s, %s)")
# Select the employees getting a raise
curA.execute(query, (date(2000, 1, 1), date(2000, 12, 31)))
# Iterate through the result of curA
for (emp_no, salary, from_date, to_date) in curA:
# Update the old and insert the new salary
new_salary = int(round(salary * Decimal('1.15')))
curB.execute(update_old_salary, (tomorrow, emp_no, from_date))
curB.execute(insert_new_salary,
(emp_no, tomorrow, date(9999, 1, 1,), new_salary))
# Commit the changes
cnx.commit()
cnx.close()