使用Python操作MySQL
前言: 最近做內部運維資料的資料倉儲,最終將Hive中的資料清洗後需要業務決策相關的資料進行結構化處理,並儲存到關係型資料庫MySQL中,以供後期對外介面使用。本篇簡單記錄下使用Python操作MySQL資料庫的簡單操作。
MySQL資料庫環境準備
注意:在當前容器化基礎設施已經全面覆蓋的時代,為了快速驗證效果,我們及其推薦使用以Docker為代表的容器化基礎設施來快速構建你的基礎環境。
在DockerHub上有豐富的基礎中介軟體的映象,我們可以使用Docker快速的構建我們的MySQL基礎環境,而不必每次重新安裝各種複雜的中介軟體環境,因為我們只是使用者,我相信每個團隊都會有專門的中介軟體維護者。好吧,如果沒有,那你依然可以自己根據實際的需求和標準進行構建Docker映象,這樣就為我們創造了一個未來很長一段時間可複用的元件。總之,想說的一件事就是,下面的MySQL環境是用Docker容器跑的。
# 確保docker環境正常
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 下載MySQL指定版本的映象
$ docker pull mysql:5.6
$ docker images | grep mysql
mysql 5.6 d1f491b20727 2 days ago 256 MB
# 建立一個mysql例項[需要指定至少一個環境變數:MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD]
$ docker run -itd --name mysql -e MYSQL_ROOT_PASSWORD="123456" -P mysql:5.6
6c4428b341516c7eeec48cbc5b658a464f76b5f7d42b3e689151392f5cd8ac56
# MySQL密碼為123456,埠為32773
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c4428b34151 mysql:5.6 "docker-entrypoint.sh" 5 seconds ago Up 3 seconds 0.0.0.0:32773->3306/tcp mysql
# mysql資料庫登入測試
$ mysql -h 127.0.0.1 -uroot -P 32773 -p123456
...
Server version: 5.6.42 MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)
# 檢視資料庫字元編碼格式
mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
至此,一個MySQL資料庫已經準備好,需要我們注意的是,因為使用的是官方的Docker image,我們需要進行相關配置的檢查和設定,否則可能會為後期的操作造成一定麻煩,比如設定資料庫的字元編碼.
讓MySQL支援中文,一般而言需要關注以下幾個點:
- 修改MySQL配置中客戶端和服務端的字元編碼為
utf8
,分別為[mysqld的default-character-set和character-set-server引數以及client的default-character-set引數]
- 修改MySQL配置中客戶端和服務端的字元編碼為
- 建立表時指定表的字元編碼(default charset=utf8;)
- 連結資料庫的時候指定連結字元編碼(charset=utf8)
- 使用Python運算元據庫時需要對Python檔案進行utf8支援(#encoding=utf-8和sys.setdefaultencoding(utf-8))
- 使用
show variables like '%char%';
命令檢查mysql字符集是否為utf8格式
,並使用SET NAMES UTF8; 或者set character_set_server = utf8;
進行設定
- 使用
使用Python進行操作MySQL
首先,在使用之前我們需要對Python版的MySQL庫有一個瞭解,當前主流的庫有MySQLdb
,PyMySQL
和SQLAlchemy
.
-
MySQLdb
:一般是Linux系統發行版中預設支援的,通常包名為Python-MySQL
,核心由C語言打造,介面精煉,效能最棒,缺點是環境依賴較多,安裝複雜,近兩年已停止更新,只支援Python2,不支援Python3 -
PyMySQL
:純python打造,介面與Python-MySQL相容,安裝方便,支援Python3 -
SQLAlchemy
: 一個ORM框架,它並不提供底層的資料庫操作,而是要藉助於MySQLdb、PyMySQL等第三方庫來完成,目前SQLAlchemy在Web程式設計領域應用廣泛備註:其實還有類似mysqlclient之類的庫,主要整合在一些web框架中作為依賴
由於為了快速實現業務邏輯,在接下來的操作中主要使用PyMySQL
庫進行運算元據庫,雖然效能不及MySQLdb
,但是可以使用pymysql.install_as_MySQLdb()
來相容MySQLdb
,在業務正式上線時可以不改變業務程式碼邏輯而平滑的使用MySQLdb
庫。
安裝pymysql庫
在Linux
環境下,大多數系統工具使用Python語言進行編寫,因此在安裝額外的Python模組時,通常會有幾種選擇:
- 使用系統自帶工具安裝
apt-get install or yum install
,該種方式會將模組預設安裝的系統環境,可能會影響系統環境
- 使用系統自帶工具安裝
- 使用Python原聲的包管理工具
pip install
,該種方式會預設安裝到pip
命令所在的Python解釋環境下,因此取決於Python環境是否獨立於系統環境的Python,通常情況下會使用pyenv
之類的工具進行環境隔離
- 使用Python原聲的包管理工具
- 使用包管理工具
conda
相關工具進行管理python,可以有效管理python多環境依賴,並且可以很方便構建資料科學相關環境.conda使用指南
- 使用包管理工具
# 安裝pymysql庫
$ pip install pymysql
or
$ conda install pymysql
python連結MySQL以及基本使用
使用pymysql庫操作mysql
$ cat pytest_mysql.py
import pymysql
# 獲取一個mysql連結物件
conn = pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=db, charset='utf8')
# 使用資料庫連結的cursor()方法獲取一個遊標物件
cursor = conn.cursor()
# 使用遊標物件的execute()方法進行執行sql語句
cursor.execute("SELECT VERSION()")
## execute方法的定義如下,其中args可以是tuple, list or dict,如果是list or tuple的話,%s會被當做查詢的一個佔位符;如果是dict的話%(name)s會被當做一個佔位符
## execute(self, query, args=None)
# 使用遊標物件的fetch類方法獲取資料
## fetchone返回一條資料,fetchall返回查詢的所有資料。fetch類方法會返回一個list型別的tuple結構型別物件.[(),()...]
onedata = cursor.fetchone()
alldata = cursor.fetchall()
# 提交資料庫操作[一般在更新資料庫操作時需要注意執行]
conn.commit()
# 及時關閉資料庫連結以及開啟的遊標[以防止在併發情況下系統開啟連線數過多]
cursor.close()
conn.close()
嘗試用python指令碼進行資料庫操作
$ cat test_show_table.py
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import pymysql
class mysqlObj:
def __init__(self,host,dbname,user,passwd,port=3306):
self.host = host
self.dbname = dbname
self.user = user
self.passwd = passwd
self.port = port
def mysqlConIns(self):
conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.passwd, db=self.dbname, charset='utf8')
return conn
def querydata(self,sql,args=None):
conn = self.mysqlConIns()
cur = conn.cursor()
cur.execute(sql,args)
alldata = cur.fetchall()
cur.close()
for data in alldata:
print(data)
conn.close()
if __name__ == '__main__':
mysqlobj = mysqlObj('localhost','mysql','root','123456',32773)
mysqlobj.querydata("show tables;")
# 對mysql庫進行檢視tables操作,返回的是一個tuple
$ python test_show_table.py
(u'columns_priv',)
(u'db',)
(u'event',)
(u'func',)
(u'general_log',)
(u'help_category',)
(u'help_keyword',)
(u'help_relation',)
(u'help_topic',)
(u'innodb_index_stats',)
(u'innodb_table_stats',)
(u'ndb_binlog_index',)
(u'plugin',)
(u'proc',)
(u'procs_priv',)
(u'proxies_priv',)
(u'servers',)
(u'slave_master_info',)
(u'slave_relay_log_info',)
(u'slave_worker_info',)
(u'slow_log',)
(u'tables_priv',)
(u'time_zone',)
(u'time_zone_leap_second',)
(u'time_zone_name',)
(u'time_zone_transition',)
(u'time_zone_transition_type',)
(u'user',)
MySQL資料庫常用的一些操作
注意:在之前我們建立的MySQL例項中僅是一個空的資料庫,在實際使用之前,我們需要進行資料庫的庫表結構建立,以及相關的資料庫授權,而這一部分操作通常會由專業的資料庫管理員(DBA)進行操作和處理
接下來對一個website
資料庫和use
表進行操作:
mysql> create database website;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS useinfo (userid int(10) primary key not null auto_increment,username varchar(20) not null,usersite varchar(50),other varchar(50)) DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.02 sec)
mysql> describe useinfo;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| userid | int(10) | NO | PRI | NULL | auto_increment |
| username | varchar(20) | NO | | NULL | |
| usersite | varchar(50) | YES | | NULL | |
| other | varchar(50) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
# 資料庫授權[授權所有的主機可以以root使用者,123456的密碼去操作website庫]
mysql> grant all on website.* to root@'%' identified by "123456";
Query OK, 0 rows affected (0.00 sec)
對指定資料庫進行相關查詢操作
# 依然是上面那個test_show_table.py指令碼,不過我們改變一下`__main__`
$ cat test_show_table.py
.....
if __name__ == '__main__':
mysqlobj = mysqlObj('localhost','website','root','123456',32773)
args = ["show tables;","describe useinfo;"]
for arg in args:
mysqlobj.querydata(arg)
# 可以看到我們的website庫下有useinfo一張表,並且該表包含userid,username,usersite,other4個欄位
$ python test_show_table.py
(u'useinfo',)
(u'userid', u'int(10)', u'NO', u'PRI', None, u'auto_increment')
(u'username', u'varchar(20)', u'NO', u'', None, u'')
(u'usersite', u'varchar(20)', u'YES', u'', None, u'')
(u'other', u'varchar(20)', u'YES', u'', None, u'')
對MySQL資料庫進行插入操作
注意:插入操作分為單條記錄插入和批量插入,一般資料庫都支援批量插入方法,在pysql中為cursor.executemany(sql,args)
為我們的mysqlObj類增加一個插入操作:
$ cat test_show_table.py
....
....
#注意插入資料時單條記錄使用tuple()型別;批量插入資料時使用list()型別
def changedata(self,sql,args=None):
conn = self.mysqlConIns()
cur = conn.cursor()
try:
#做一個粗暴的判斷當args是list時就進行批量插入
if isinstance(args,list):
#executemany(sql,args)方法args支援tuple或者list型別
cur.executemany(sql,args)
else:
#execute(sql,args)方法args支援string,tuple,list,dict
cur.execute(sql,args)
conn.commit()
except Exception as e:
conn.rollback()
print(e)
finally:
cur.close()
conn.close()
....
...
if __name__ == '__main__':
mysqlobj = mysqlObj('localhost','website','root','123456',32773)
'''
args = ["show tables;","describe useinfo;"]
for arg in args:
mysqlobj.querydata(arg)
'''
#插入一條資料
sql = "insert into useinfo (username) values(%s)"
arg = "彪哥"
mysqlobj.changedata(sql,arg)
sql1 = "insert into useinfo (username,usersite) values(%s,%s)"
arg1 = ("xxbandy","http://xxbandy.github.io")
mysqlobj.changedata(sql1,arg1)
#批量插入資料
argslist = [("彪哥","http://xxbandy.github.io"),("bgbiao","https://www.jianshu.com/u/9c46ece5b7bd")]
mysqlobj.changedata(sql1,argslist)
#查詢資料
mysqlobj.querydata("select * from useinfo")
print("updating the data")
#更新資料[需要注意的是指定了欄位之後由於usersite是varchar型別,佔位符必須是"%s",如果是'%s'會有問題]
data = "https://my.oschina.net/xxbAndy"
mysqlobj.changedata('update useinfo set usersite=%s where userid = 1',data)
mysqlobj.querydata("select * from useinfo")
# 插入資料並檢視資料
$ python /tmp/abc.py
(1, u'\u5f6a\u54e5', None, None)
(2, u'xxbandy', u'http://xxbandy.github.io', None)
(3, u'\u5f6a\u54e5', u'http://xxbandy.github.io', None)
(4, u'bgbiao', u'https://www.jianshu.com/u/9c46ece5b7bd', None)
updating the data
(1, u'\u5f6a\u54e5', u'https://my.oschina.net/xxbAndy', None)
(2, u'xxbandy', u'http://xxbandy.github.io', None)
(3, u'\u5f6a\u54e5', u'http://xxbandy.github.io', None)
(4, u'bgbiao', u'https://www.jianshu.com/u/9c46ece5b7bd', None)
# 資料庫查詢記錄
mysql> select * from website.useinfo;
+--------+----------+----------------------------------------+-------+
| userid | username | usersite | other |
+--------+----------+----------------------------------------+-------+
| 1 | 彪哥 | https://my.oschina.net/xxbAndy | NULL |
| 2 | xxbandy | http://xxbandy.github.io | NULL |
| 3 | 彪哥 | http://xxbandy.github.io | NULL |
| 4 | bgbiao | https://www.jianshu.com/u/9c46ece5b7bd | NULL |
+--------+----------+----------------------------------------+-------+
原始碼
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import pymysql
class mysqlObj:
def __init__(self,host,dbname,user,passwd,port=3306):
self.host = host
self.dbname = dbname
self.user = user
self.passwd = passwd
self.port = port
def mysqlConIns(self):
conn = pymysql.connect(host=self.host, port=self.port, user=self.user, passwd=self.passwd, db=self.dbname, charset='utf8')
return conn
def querydata(self,sql,args=None):
conn = self.mysqlConIns()
cur = conn.cursor()
cur.execute(sql,args)
alldata = cur.fetchall()
cur.close()
for data in alldata:
print(data)
conn.close()
#注意插入資料時單條記錄使用tuple()型別;批量插入資料時使用list()型別
def changedata(self,sql,args=None):
conn = self.mysqlConIns()
cur = conn.cursor()
try:
#做一個粗暴的判斷當args是list時就進行批量插入
if isinstance(args,list):
#executemany(sql,args)方法args支援tuple或者list型別
cur.executemany(sql,args)
else:
#execute(sql,args)方法args支援string,tuple,list,dict
cur.execute(sql,args)
conn.commit()
except Exception as e:
conn.rollback()
print(e)
finally:
cur.close()
conn.close()
if __name__ == '__main__':
mysqlobj = mysqlObj('localhost','website','root','123456',32773)
'''
args = ["show tables;","describe useinfo;"]
for arg in args:
mysqlobj.querydata(arg)
'''
#插入一條資料
sql = "insert into useinfo (username) values(%s)"
arg = "彪哥"
mysqlobj.changedata(sql,arg)
sql1 = "insert into useinfo (username,usersite) values(%s,%s)"
arg1 = ("xxbandy","http://xxbandy.github.io")
mysqlobj.changedata(sql1,arg1)
#批量插入資料
argslist = [("彪哥","http://xxbandy.github.io"),("bgbiao","https://www.jianshu.com/u/9c46ece5b7bd")]
mysqlobj.changedata(sql1,argslist)
#查詢資料
mysqlobj.querydata("select * from useinfo")
print("updating the data")
#更新資料
data = "https://my.oschina.net/xxbAndy"
mysqlobj.changedata('''update useinfo set usersite=%s where userid = 1''',data)
mysqlobj.querydata("select * from useinfo")
相關文章
- 使用mysql-connector-python操作MYSQL資料庫MySqlPython資料庫
- Python 操作 MySQLPythonMySql
- python操作mysqlPythonMySql
- Python3進階——使用PyMySQL操作MySQLPythonMySql
- Python如何操作MySQLPythonMySql
- Python操作MySQL分享PythonMySql
- python怎麼操作mysqlPythonMySql
- openresty使用lua操作mysqlRESTMySql
- python的ORM技術:使用sqlalchemy操作mysql資料庫PythonORMMySql資料庫
- python資料庫(mysql)操作Python資料庫MySql
- python 操作mysql資料庫PythonMySql資料庫
- Python Mysql 資料庫操作PythonMySql資料庫
- python操作mysql資料庫PythonMySql資料庫
- Python之 操作 MySQL 資料庫PythonMySql資料庫
- Python 操作 MySQL 的5種方式PythonMySql
- node.js使用Sequelize 操作mysqlNode.jsMySql
- 使用OTL操作MySQL資料庫MySql資料庫
- 01-python操作Mysql資料庫PythonMySql資料庫
- Python 操作 MySQL 的正確姿勢PythonMySql
- Python3 MySQL 資料庫操作PythonMySql資料庫
- 使用Python構建MySQL資料處理系統的操作方法PythonMySql
- 幾個MySQL在Python中操作示例,MySQL利用於Python的實戰!MySqlPython
- python 使用csv的基本操作Python
- 使用 Couchdb-python 操作 CouchDBPython
- python操作MySQL資料庫連線(pymysql)PythonMySql資料庫
- MySQL Workbench 中文使用指南 - 如何使用 Workbench 操作 MySQL 資料庫教程MySql資料庫
- MySQL學習筆記-使用Navicat操作MySQL資料庫MySql筆記資料庫
- 如何使用PYTHON操作攝像頭Python
- python使用loguru操作日誌Python
- python操作Excel讀寫--使用xlrdPythonExcel
- 全棧 – 12 資料庫 用Python操作MySQL全棧資料庫PythonMySql
- Python 連線mysql資料庫進行操作PythonMySql資料庫
- 全棧 - 12 資料庫 用Python操作MySQL全棧資料庫PythonMySql
- python 操作 mysql 只看這篇就夠了PythonMySql
- Python操作MySQL資料庫的5種方式PythonMySql資料庫
- mysql操作MySql
- day40:MySQL:python操作mysql:pymysql模組&SQL隱碼攻擊MySqlPython
- python使用mysql資料庫PythonMySql資料庫