三種驅(qū)動(dòng)mysql.connector、PyMySQL怔匣、mysqldb使用和比較
mysql-connector-python
此為廖雪峰老師教程中所用驅(qū)動(dòng)握联,為python官方驅(qū)動(dòng)。安裝命令:
pip install mysql-connector-python --allow-external mysql-connector-python
或者
pip install mysql-connector
使用mysql.connector訪問數(shù)據(jù)庫:
import mysql.connector
# password設(shè)為mysql的root口令
conn = mysql.connector.connect(user='root', password='password', database='test')
cursor = conn.cursor()
# 創(chuàng)建user表
cursor.execute('要執(zhí)行的sql語句')
# 提交事務(wù)
conn.commit()
# 關(guān)閉Cursor和Connection:
cursor.close()
conn.close()
PyMySQL 驅(qū)動(dòng)
PyMySQL僅限于 Python3.x 版本中連接 MySQL 每瞒。
- 安裝命令:
pip3 install PyMySQL
若pip安裝失敗金闽,可使用git命令或者手動(dòng)下載源安裝包后,進(jìn)入工程目錄使用python命令手動(dòng)安裝:
cd PyMySQL/
python3 setup.py install
- 使用PyMySQL訪問數(shù)據(jù)庫-建表:
#!/usr/bin/python3
import pymysql
# 打開數(shù)據(jù)庫連接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )
# 使用 cursor() 方法創(chuàng)建一個(gè)游標(biāo)對(duì)象 cursor
cursor = db.cursor()
# 使用 execute() 方法執(zhí)行 SQL剿骨,如果表存在則刪除
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
# 使用預(yù)處理語句創(chuàng)建表
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor.execute(sql)
# 關(guān)閉數(shù)據(jù)庫連接
db.close()
- 使用PyMySQL訪問數(shù)據(jù)庫-插入呐矾、更新、刪除數(shù)據(jù):
注意事務(wù)提交以及錯(cuò)誤回滾處理
#!/usr/bin/python3
import pymysql
# 打開數(shù)據(jù)庫連接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )
# 使用cursor()方法獲取操作游標(biāo)
cursor = db.cursor()
# SQL 插入語句
# 此處可將sql換為update懦砂、delete等語句
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
LAST_NAME, AGE, SEX, INCOME) \
VALUES ('%s', '%s', %s, '%s', %s)" % \
('Mac', 'Mohan', 20, 'M', 2000)
try:
# 執(zhí)行sql語句
cursor.execute(sql)
# 執(zhí)行sql語句
db.commit()
except:
# 發(fā)生錯(cuò)誤時(shí)回滾
db.rollback()
# 關(guān)閉數(shù)據(jù)庫連接
db.close()
- 使用PyMySQL訪問數(shù)據(jù)庫-查詢:
可使用fetchall()等方法對(duì)查詢結(jié)果進(jìn)行獲取和進(jìn)一步處理蜒犯,見代碼中注釋
#!/usr/bin/python3
import pymysql
# 打開數(shù)據(jù)庫連接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )
# 使用cursor()方法獲取操作游標(biāo)
cursor = db.cursor()
# SQL 查詢語句
sql_query = "SELECT * FROM EMPLOYEE \
WHERE INCOME > %s" % (1000)
try:
# 執(zhí)行SQL語句
cursor.execute(sql_query)
# fetchone(): 該方法獲取下一個(gè)查詢結(jié)果集。結(jié)果集是一個(gè)對(duì)象
# fetchall(): 接收全部的返回結(jié)果行.
# rowcount: 這是一個(gè)只讀屬性荞膘,并非方法罚随,直接返回執(zhí)行execute()方法后影響的行數(shù)。
results = cursor.fetchall()
for row in results:
pass
except:
print ("Error: unable to fetch data")
# 關(guān)閉數(shù)據(jù)庫連接
db.close()
MySQLdb驅(qū)動(dòng)
僅支持linux的python2.x版本羽资。用法同上類似淘菩,安裝:
pip install MySQLdb
比較和總結(jié)
- mysql.connector作為官方版本,在Python中重新實(shí)現(xiàn)MySQL協(xié)議屠升,速度相對(duì)最慢潮改,但因?yàn)椴灰蕾嚻渌鼛欤虼俗畋銛y腹暖;
- PyMySQL 限制于Python3.x 版本汇在;
- MySQLdb限制于Python2.x 版本,且不支持windows脏答。
因此推薦使用PyMySQL糕殉。
SSH連接Mysql
基于pymysql與sshtunnel,實(shí)現(xiàn)mysql跳轉(zhuǎn)連接殖告,用于服務(wù)器無法直接本地連接的場(chǎng)景阿蝶。即:在本地(記為地址A),通過SSH中間服務(wù)器B黄绩,連接遠(yuǎn)程MYSQL服務(wù)器C羡洁。
下述代碼中地址及端口,根據(jù)實(shí)際網(wǎng)絡(luò)策略進(jìn)行配置:
from pymysql import connect
from sshtunnel import SSHTunnelForwarder
# 指定SSH遠(yuǎn)程跳轉(zhuǎn)
server = SSHTunnelForwarder(ssh_address_or_host=('IP地址B', B端口號(hào)), # 指定SSH中間登錄地址和端口號(hào)
ssh_username='user_name_b', # 指定地址B的SSH登錄用戶名
ssh_password='pwd_b', # 指定地址B的SSH登錄密碼
local_bind_address=('127.0.0.1', A端口號(hào)), # 綁定本地地址A(默認(rèn)127.0.0.1)及與B相通的端口(根據(jù)網(wǎng)絡(luò)策略配置爽丹,若端口全放筑煮,則此行無需配置,使用默認(rèn)即可)
remote_bind_address=('IP地址C', 3306) # 指定最終目標(biāo)C地址习劫,端口號(hào)為mysql默認(rèn)端口號(hào)3306
)
server.start()
# 打印本地端口咆瘟,以檢查是否配置正確
print(server.local_bind_port)
# 設(shè)置mysql連接參數(shù),地址與端口均必須設(shè)置為本地地址與端口
# 用戶名和密碼以及數(shù)據(jù)庫名根據(jù)自己的數(shù)據(jù)庫進(jìn)行配置
db = connect(host="127.0.0.1", port=server.local_bind_port, user="root", passwd="root_pwd", db="test_db")
cursor = db.cursor()
sql = "select COUNT(1) from table1"
try:
# 執(zhí)行SQL語句檢查是否連接成功
cursor.execute("SELECT VERSION()")
result = cursor.fetchone()
print("Database version : %s " % result)
#執(zhí)行查詢語句
cursor.execute(sql)
result = cursor.fetchone()
print("sql result : %s" % result)
except:
print("Error: unable to fetch data")
# 關(guān)閉連接
db.close()
server.close()