通過Python連接到MySQL數(shù)據(jù)庫
如何將你的Python筆記本連接到MySQL數(shù)據(jù)庫
通常情況下属百,數(shù)據(jù)科學(xué)家或分析師必須訪問數(shù)據(jù)庫蛛蒙,例如用于特定的分析。通常情況下号枕,這些數(shù)據(jù)庫是MySQL數(shù)據(jù)庫权悟,這里你可以使用MySQL連接器從Jupyter筆記本訪問MySQL數(shù)據(jù)庫砸王。
代碼塊
https://pypi.org/project/mysql-connector-python/
https://dev.mysql.com/doc/connector-python/en/
第一步是通過!"pip安裝 "命令來安裝連接器。
pip install mysql-connector-python
之后峦阁,你就可以使用該庫并連接到數(shù)據(jù)庫了谦铃。
導(dǎo)入連接器
輸入mysql.connector
連接到數(shù)據(jù)庫
#Import the Connector
import mysql.connector
# Connecting to the database
conn = mysql.connector.connect(user = ‘username’,host = ‘localhost’,database = ‘database_name’)
然后在游標(biāo)對(duì)象的幫助下,你可以查詢表榔昔。
初始化一個(gè)游標(biāo)對(duì)象
cursorObject = dataBase.cursor()
選擇查詢
query = "SELECT NAME, FORNAME FROM CUSTOMER"
cursorObject.execute(query)
result = cursorObject.fetchall()
從這里開始驹闰,你可以使用結(jié)果進(jìn)行數(shù)據(jù)準(zhǔn)備和聚合。最后但并非最不重要的是--完成后一定要斷開與服務(wù)器的連接件豌。
與服務(wù)器斷開連接
conn.close()
這篇文章給了你一個(gè)簡短的概述,告訴你如何在MySQL連接器的幫助下通過Python筆記本輕松訪問MySQL數(shù)據(jù)庫控嗜。除了閱讀茧彤,你當(dāng)然還可以執(zhí)行許多其他的操作,比如疆栏。
創(chuàng)建/刪除一個(gè)表
插入記錄
以及更多的操作
如果你想更深入地了解曾掂,你可以去官方網(wǎng)站[1]
Python數(shù)據(jù)庫訪問 - Python 3 MySQL
Python數(shù)據(jù)庫訪問
一個(gè)數(shù)據(jù)庫是一個(gè)通過列相互關(guān)聯(lián)的表的集合。對(duì)于大多數(shù)現(xiàn)實(shí)世界的項(xiàng)目壁顶,數(shù)據(jù)庫是必須的珠洗。我們可以使用SQL(結(jié)構(gòu)化查詢語言)來創(chuàng)建、訪問和操作數(shù)據(jù)若专。我們還可以利用規(guī)范化來避免數(shù)據(jù)的冗余许蓖。
對(duì)于數(shù)據(jù)庫編程,Python支持許多數(shù)據(jù)庫服務(wù)器:
MySQL调衰、Oracle膊爪、PostgreSQL、SQLite嚎莉、Sybase米酬、Microsoft SQL Server、mSQL趋箩、Microsoft Access赃额,... ...
它還支持?jǐn)?shù)據(jù)查詢語句加派、數(shù)據(jù)定義語言(DDL)和數(shù)據(jù)操作語言(DML)。Python的標(biāo)準(zhǔn)數(shù)據(jù)庫接口是Python DB-API跳芳。為此芍锦,我們有MySQL的MySQLdb模塊。這與數(shù)據(jù)庫引擎無關(guān)筛严;所以我們可以編寫Python腳本來訪問任何數(shù)據(jù)庫引擎醉旦。然而,這與Python 3并不兼容桨啃。
因此车胡,在這個(gè)Python數(shù)據(jù)庫訪問教程中,我們使用PyMySQL模塊照瘾。
用Python進(jìn)行數(shù)據(jù)庫編程的優(yōu)勢
使用Python匈棘,我們有以下好處。
獨(dú)立于平臺(tái)
速度更快析命,效率更高
攜帶方便
支持關(guān)系型數(shù)據(jù)庫系統(tǒng)
易于遷移和移植數(shù)據(jù)庫應(yīng)用接口
支持SQL游標(biāo)
它可以處理開放和關(guān)閉的連接
PyMySQL和安裝
PyMySQL實(shí)現(xiàn)了Python數(shù)據(jù)庫API 2.0主卫。在這個(gè)Python數(shù)據(jù)庫教程中,我們將使用它從Python連接到一個(gè)MySQL數(shù)據(jù)庫服務(wù)器鹃愤。我們有以下要求來安裝PyMySQL------簇搅。
a. Python(任何一種)
CPython>=2.6或>=3.3
PyPy>=4.0
IronPython 2.7
遵循此鏈接了解Python如何重命名文件--單個(gè)和多個(gè)文件
b. MySQL(任何一種)
MySQL>=4.1
MariaDB>=5.1
要安裝它,請(qǐng)?jiān)诿钐崾痉逻\(yùn)行以下命令
C:\Users\lifei>pip install PyMySQL
采集PyMySQL
Using cached https://files.pythonhosted.org/packages/2f/be/4310bb405eb83b615cf9bd4501942d9ff000d8b9372ce84e920facbf5c36/PyMySQL-0.9.0-py2.py3-none-any.whl
采集密碼學(xué)(來自PyMySQL)
Downloading https://files.pythonhosted.org/packages/67/62/67faef32908026e816a74b4b97491f8b9ff393d2951820573599c105cc32/cryptography-2.2.2-cp36-cp36m-win_amd64.whl (1.3MB)
100% |████████████████████████████████| 1.3MB 596kB/s
收集idna>=2.1 (從密碼學(xué)->PyMySQL)
Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB)
100% |████████████████████████████████| 61kB 1.3MB/s
收集asn1crypto>=0.21.0 (來自cryptography->PyMySQL)
Using cached https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl
收集 six>=1.4.1 (從密碼學(xué)->PyMySQL)
讓我們閱讀Python Zipfile--Python中Zipfiles的好處软吐、模塊瘩将、對(duì)象
Using cached https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
收集 cffi>=1.7; platform_python_implementation != "PyPy" (from cryptography->PyMySQL)
Downloading https://files.pythonhosted.org/packages/2f/85/a9184548ad4261916d08a50d9e272bf6f93c54f3735878fbfc9335efd94b/cffi-1.11.5-cp36-cp36m-win_amd64.whl (166kB)
100% |████████████████████████████████| 174kB 568kB/s
收集 pycparser (from cffi>=1.7; platform_python_implementation != "PyPy" ->cryptography->PyMySQL)
Using cached https://files.pythonhosted.org/packages/8c/2d/aad7f16146f4197a11f8e91fb81df177adcc2073d36a17b1491fd09df6ed/pycparser-2.18.tar.gz
安裝收集的軟件包:idna, asn1crypto, six, pycparser, cffi, cryptography, PyMySQL
運(yùn)行 setup.py install for pycparser ... done
成功地安裝了 PyMySQL-0.9.0 asn1crypto-0.24.0 cffi-1.11.5 cryptography-2.2.2 idna-2.7 pycparser-2.18 six-1.11.0
另外,確保在你的機(jī)器上安裝一個(gè)數(shù)據(jù)庫服務(wù)器凹耙。在這篇文章中姿现,我們使用MySQL。我們從這里下載它--
dev.mysql.com/downloads/mysql
連接Python數(shù)據(jù)庫
現(xiàn)在你已經(jīng)安裝好了一切肖抱,讓我們開始連接數(shù)據(jù)庫备典。讓我們先創(chuàng)建一個(gè)數(shù)據(jù)庫。
a. 如何創(chuàng)建Python數(shù)據(jù)庫意述?
以及更多的操作
mysql> create database demo;
Query OK, 1 row affected (0.21 sec)
mysql> use demo;
Database changed
mysql> create user ‘a(chǎn)yushi’@’localhost’ IDENTIFIED BY ‘yourpassword’
-> ;
Query OK, 0 rows affected (0.21 sec)
mysql> grant all on demo.* to ‘a(chǎn)yushi’@’localhost’;
Query OK, 0 rows affected (0.22 sec)
mysql> create table student(fname varchar(20), lname varchar(20), age int, enrolment_no varchar(12));
Query OK, 0 rows affected (0.62 sec)
b. 如何連接Python數(shù)據(jù)庫提佣?
import pymysql
db=pymysql.connect(“l(fā)ocalhost”,”ayushi”,”yourpassword”,”demo”) #This saves a connection object into db
cursor=db.cursor()
cursor.execute(“SELECT VERSION()”)
1
print(f”You’re running version {cursor.fetchone()}”)
You’re running version (‘8.0.11’,)
db.close() #Closing the database connection
A cursor is an object that submits different SQL statements to the database server. A cursor returns a result set object.
游標(biāo)是一個(gè)可以向數(shù)據(jù)庫服務(wù)器提交不同SQL語句的對(duì)象。游標(biāo)返回一個(gè)結(jié)果集對(duì)象荤崇。
讓我們了解一下Python工具--Python的4個(gè)主要實(shí)用工具
如何在Python數(shù)據(jù)庫中創(chuàng)建表镐依?
現(xiàn)在讓我們逐一看看所有的操作,從創(chuàng)建一個(gè)表開始天试。
import pymysql
db=pymysql.connect(“l(fā)ocalhost”,”ayushi”,”yourpassword”,”demo”)
caching sha2: succeeded by fast path.
cursor=db.cursor()
cursor.execute(“DROP TABLE IF EXISTS student”) #This drops the table and replaces it
query=”””CREATE TABLE student(
fname VARCHAR(20), lname VARCHAR(20),
age INT, enrolment_no VARCHAR(12))”””
cursor.execute(query)
db.close()
如何在Python數(shù)據(jù)庫中插入一條記錄槐壳?
讓我們?cè)囍?student'中插入一條記錄。
import pymysql
db=pymysql.connect(“l(fā)ocalhost”,”ayushi”,”yourpassword”,”demo”)
caching sha2: succeeded by fast path.
cursor=db.cursor()
query=’INSERT INTO student VALUES(“Ayushi”,”Sharma”,22,”0812CS141028")’
try:
cursor.execute(query)
db.commit() #Commit writing to the database
except:
db.rollback() #Rollback the transaction if not complete
1
db.close()
讓我們檢查一下這是否對(duì)數(shù)據(jù)庫做了任何改變喜每。在命令提示符下
mysql> select * from student;
+ - - - - + - - - - + - - - + - - - - - - - +
| fname | lname | age | enrolment_no |
+ - - - - + - - - - + - - - + - - - - - - - +
| Ayushi | Sharma | 22 | 0812CS141028 |
+ - - - - + - - - - + - - - + - - - - - - - +
一組中的1行 (0.00 sec)
如何在Python數(shù)據(jù)庫中讀取記錄务唐?
現(xiàn)在我們?nèi)绾螐臄?shù)據(jù)庫中獲取數(shù)值雳攘?讓我們舉個(gè)例子,從'student'中獲取大于22歲的學(xué)生記錄枫笛。為此我們添加了另一條記錄吨灭。
import pymysql
db=pymysql.connect(“l(fā)ocalhost”,”ayushi”,”yourpassword”,”demo”)
caching sha2: succeeded by fast path.
cursor=db.cursor()
query=”select * from student where age>22"
try:
cursor.execute(query)
resultset=cursor.fetchall() #To fetch all records that satisfy
for record in resultset:
fname=record[0]
lname=record[1]
age=record[2]
enrolment_no=record[3]
print(f”Student: {fname} {lname}; Enrolment: {enrolment_no}; Age: {age}”)
except:
print(“Sorry, we encountered a problem”)
1
Student: Megha Sharma; Enrolment: 0812CS141015; Age: 24
db.close()
我們有以下方法和屬性-
fetchone()- 這個(gè)方法從查詢的結(jié)果集中獲取下一條記錄。
fetchall()- 這是獲取整個(gè)結(jié)果集刑巧;它將不包括已經(jīng)提取的記錄喧兄。
rowcount- 這是一個(gè)屬性。它返回一個(gè)整數(shù)啊楚,表示對(duì)execute()的調(diào)用所影響的記錄數(shù)吠冤。
請(qǐng)看Python 3中的XML處理 | XML解析器
如何在Python數(shù)據(jù)庫中更新記錄?
要更新現(xiàn)有的記錄恭理,我們可以簡單地使用一個(gè)SQL查詢來實(shí)現(xiàn)拯辙。
import pymysql
db=pymysql.connect(“l(fā)ocalhost”,”ayushi”,”yourpassword”,”demo”)
caching sha2: succeeded by fast path.
cursor=db.cursor()
query=”update student set age=age+1 where age<=22"
try:
cursor.execute(query)
db.commit()
except:
db.rollback()
1
db.close()
讓我們看看這是否對(duì)實(shí)際的數(shù)據(jù)庫做了任何改變。在你的命令提示符中
mysql> select * from student;
+ - - - - + - - - - + - - - + - - - - - - - +
| fname | lname | age | enrolment_no |
+ - - - - + - - - - + - - - + - - - - - - - +
| Ayushi | Sharma | 23 | 0812CS141028 |
| Megha | Sharma | 24 | 0812CS141015 |
+ - - - - + - - - - + - - - + - - - - - - - +
一組有2行 (0.00 sec)
如何在Python數(shù)據(jù)庫中刪除記錄颜价?
我們也可以用Python從數(shù)據(jù)庫中刪除記錄涯保。
import pymysql
db=pymysql.connect(“l(fā)ocalhost”,”ayushi”,”swaysway7!”,”demo”)
caching sha2: succeeded by fast path.
cursor=db.cursor()
query=”delete from student where age>23"
try:
cursor.execute(query)
db.commit()
except:
db.rollback()
1
db.close()
而在命令提示符下
mysql> select * from student;
+ - - - - + - - - - + - - - + - - - - - - - +
| fname | lname | age | enrolment_no |
+ - - - - + - - - - + - - - + - - - - - - - +
| Ayushi | Sharma | 23 | 0812CS141028 |
+ - - - - + - - - - + - - - + - - - - - - - +
一組中的1行 (0.00秒)
提交、回滾和斷開連接
提交命令告訴數(shù)據(jù)庫最終完成對(duì)數(shù)據(jù)庫的寫入周伦∠Υ海回滾可以讓我們恢復(fù)變化,回到之前的狀態(tài)专挪。對(duì)于提交及志,你可以使用commit(),而對(duì)于回滾狈蚤,你可以使用rollback()困肩。
讓我們討論一下Python網(wǎng)絡(luò)編程|Python Socket編程
在我們完成了對(duì)數(shù)據(jù)庫的操作之后划纽,我們應(yīng)該關(guān)閉數(shù)據(jù)庫以釋放資源脆侮。為此我們使用close()。如果你不明白這些勇劣,我們建議閱讀一下數(shù)據(jù)庫中事務(wù)的基本屬性靖避。
交易中的錯(cuò)誤
當(dāng)持有一個(gè)事務(wù)時(shí),你可能會(huì)遇到十種不同的錯(cuò)誤比默。
Python數(shù)據(jù)庫訪問 - Python 3 MySQL
a. 錯(cuò)誤
這是錯(cuò)誤的基類幻捏,是StandardError的子類。
b. InterfaceError
這是 Error 的一個(gè)子類命咐,Python 使用它來處理與數(shù)據(jù)庫訪問模塊有關(guān)的錯(cuò)誤篡九。
c. 數(shù)據(jù)庫錯(cuò)誤(DatabaseError
這是 Error 的一個(gè)子類,Python 使用它來處理數(shù)據(jù)庫錯(cuò)誤醋奠。
d. 操作性錯(cuò)誤
這是 DatabaseError 的一個(gè)子類榛臼。當(dāng)Python失去與數(shù)據(jù)庫的連接時(shí)伊佃,它會(huì)拋出這個(gè)錯(cuò)誤。
這可能發(fā)生在我們沒有選擇一個(gè)數(shù)據(jù)庫的時(shí)候沛善。
讓我們來探索Python Web框架--一個(gè)帶有解釋的詳細(xì)列表
e. DataError
這是DatabaseError的一個(gè)子類航揉。當(dāng)數(shù)據(jù)中出現(xiàn)錯(cuò)誤時(shí),Python 會(huì)使用它金刁。
f. 內(nèi)部錯(cuò)誤
這是 DatabaseError 的一個(gè)子類帅涂。Python 使用它來處理我們用于數(shù)據(jù)庫訪問的模塊內(nèi)部的錯(cuò)誤。
g. 完整性錯(cuò)誤(IntegrityError
也是DatabaseError的一個(gè)子類尤蛮。Python 用它來處理對(duì)關(guān)系完整性有損害的情況媳友。
當(dāng)你試圖在數(shù)據(jù)庫中輸入重復(fù)的記錄時(shí),這可能發(fā)生抵屿。
h. 編程錯(cuò)誤
這是DatabaseError的一個(gè)子類庆锦。像糟糕的表名這樣的錯(cuò)誤會(huì)導(dǎo)致這種情況。
當(dāng)我們?cè)噲D創(chuàng)建一個(gè)重復(fù)的數(shù)據(jù)庫時(shí)轧葛,這可能會(huì)發(fā)生搂抒。
i. 不支持的錯(cuò)誤
是DatabaseError的一個(gè)子類。當(dāng)我們?cè)噲D調(diào)用它不支持的功能時(shí)尿扯,Python 會(huì)引發(fā)這個(gè)錯(cuò)誤求晶。
j. 警告
這是 StandardError 的一個(gè)子類。Python 用它來處理非致命的問題衷笋。
所以芳杏,這就是關(guān)于Python數(shù)據(jù)庫訪問的全部內(nèi)容。希望你喜歡我們的解釋辟宗。
https://i.imgur.com/W3G8gw8.png
總結(jié)
因此爵赵,現(xiàn)在你知道了如何使用Python和MySQL訪問數(shù)據(jù)庫。此外泊脐,我們看到了如何進(jìn)行Python數(shù)據(jù)庫訪問空幻,以及如何在Python 3中創(chuàng)建數(shù)據(jù)庫,還進(jìn)行了插入容客、讀取秕铛、更新、刪除缩挑、提交但两、回滾和斷開連接等操作。最后供置,我們介紹了如何處理Python數(shù)據(jù)庫訪問和PyMySQL中的錯(cuò)誤以及安裝和Python數(shù)據(jù)庫訪問的好處谨湘。今天就講到這里。請(qǐng)?jiān)谙旅娴脑u(píng)論中提出任何疑問。
用Python為MySQL上傳CSV到JSON
無可否認(rèn)紧阔,我已經(jīng)一頭扎進(jìn)了MySQL中的JSON世界谎僻。我也對(duì)Python情有獨(dú)鐘,我發(fā)現(xiàn)自己在日常工作中作為管道調(diào)查數(shù)據(jù)分析師使用了大量的Python寓辱。
CSV無處不在! 工作中的數(shù)據(jù)艘绍,網(wǎng)絡(luò)上的數(shù)據(jù),甚至是我的個(gè)人生活(你會(huì)看到)秫筏。對(duì)于使用這兩種技術(shù)的人來說诱鞠,將CSV數(shù)據(jù)加載到MySQL中并不新鮮。事實(shí)上这敬,有幾種方法可以讓你的CSV數(shù)據(jù)進(jìn)入MySQL航夺。
我寫了一篇文章,Pyodbc SQL CRUD - Create: 例子崔涂,你可以閱讀我寫的關(guān)于使用Pyodbc模塊加載CSV數(shù)據(jù)的文章阳掐。但是,如何將CSV數(shù)據(jù)(通常是字符串)類型轉(zhuǎn)換為兼容的JSON數(shù)據(jù)類型冷蚂?然后將JSON數(shù)據(jù)推送到MySQL的JSON列中缭保?我的朋友們,這就是這篇文章的重點(diǎn)蝙茶。事實(shí)證明艺骂,Python的csv和json標(biāo)準(zhǔn)庫使整個(gè)過程幾乎沒有痛苦。繼續(xù)閱讀隆夯,看看我設(shè)計(jì)的一個(gè)簡單腳本...
使用的操作系統(tǒng)钳恕、軟件和數(shù)據(jù)庫。
OpenSuse Leap 15.1
Python 3.7.3
在Python中處理JSON數(shù)據(jù)
https://realpython.com/python-json/
如何在Python中格式化日期
https://stackabuse.com/converting-strings-to-datetime-in-python/
在Python中把字符串轉(zhuǎn)換為日期時(shí)間
https://stackabuse.com/how-to-format-dates-in-python/
我有一個(gè)CSV文件蹄衷,我存儲(chǔ)了行走的統(tǒng)計(jì)數(shù)據(jù)有序。
帶有數(shù)據(jù)的CSV文件...
為了存儲(chǔ)JSON數(shù)據(jù)路召,我們需要一個(gè)JSON列往毡。表'j_walking'是目標(biāo)目的地鼻疮,并且有一個(gè)'stats'列混狠,就是為了這個(gè)目的堪藐。
MySQL localhost:33060+ ssl walking SQL > DESC j_walking;
+ - - - -+ - - - + - - - + - - -+ - - - - -+ - - - -+
| 字段 | 類型 | 空值 | 關(guān)鍵 | 默認(rèn) | 額外 |
+ - - - -+ - - - + - - - + - - -+ - - - - -+ - - - -+
| stats | json | YES | NULL | |
+ - - - -+ - - - + - - - + - - -+ - - - - -+ - - - -+
一組中的1行 (0.0034秒)
下面顯示的當(dāng)前數(shù)據(jù)行提供了一個(gè)格式和模式的例子旭咽。
MySQL localhost:33060+ ssl walking SQL > SELECT JSON_PRETTY(stats) FROM j_walking LIMIT 3\G
*************************** 1. row ***************************
JSON_PRETTY(stats): {
“mph”: 3.2,
“duration”: “00:33:18”,
“cal_burned”: 181.1,
“day_walked”: “2019–01–02”,
“shoes_worn”: “Keen Koven WP”,
“miles_walked”: 1.76
}
*************************** 2. row ***************************
JSON_PRETTY(stats): {
“mph”: 3.2,
“duration”: “00:38:07”,
“cal_burned”: 207.3,
“day_walked”: “2019–01–07”,
“shoes_worn”: “Oboz Sawtooth Low”,
“miles_walked”: 2.03
}
*************************** 3. row ***************************
JSON_PRETTY(stats): {
“mph”: 3.2,
“duration”: “00:40:07”,
“cal_burned”: 218.2,
“day_walked”: “2019–01–08”,
“shoes_worn”: “Oboz Sawtooth Low”,
“miles_walked”: 2.13
}
3 rows in set (0.0011 sec)
在對(duì)一個(gè)可行的函數(shù)進(jìn)行原型設(shè)計(jì)的過程中幼苛,下圖所示的JSON輸出示例并不完全符合要求的格式大咱。雖然它類似于我想要的最終數(shù)據(jù)結(jié)構(gòu)恬涧,但所有的數(shù)字值都是字符串,而不是它們的數(shù)字等價(jià)物碴巾。
所有數(shù)據(jù)值為字符串的JSON文件...
這段工作代碼提供了所需的解決方案溯捆。通過各種方式,精明的讀者和開發(fā)者請(qǐng)?jiān)谙旅嬖u(píng)論任何你認(rèn)為我應(yīng)該修改和改進(jìn)的地方。
import csv
import json
import datetime
import os
‘’’
Simple script that converts csv file to json file
‘’’
def csv_to_json(csv_in_file, out_json_file):
try:
if os.path.isfile(csv_in_file):
# CSV 1st row header names
fieldnames = (‘day_walked’, ‘cal_burned’, ‘miles_walked’,
‘duration’, ‘mph’, ‘shoe_id’)
with open(csv_in_file, ‘r’) as f:
csv_reader = csv.DictReader(f, fieldnames)
next(csv_reader) # Advancing past the header row
with open(out_json_file, ‘w’) as json_f:
for row in csv_reader:
# Typecasting all columns to appropriate data type
row[‘day_walked’] = datetime.datetime.strptime(
row[‘day_walked’], ‘%Y-%m-%d’).date()
row[‘cal_burned’] = float(row[‘cal_burned’])
row[‘miles_walked’] = float(row[‘miles_walked’])
row[‘duration’] = datetime.datetime.strptime(
row[‘duration’], ‘%H:%M:%S’).time()
row[‘mph’] = float(row[‘mph’])
row[‘shoe_id’] = int(row[‘shoe_id’])
json.dump(row, json_f, default=str)
json_f.write(‘\n’)
else:
print(‘That CSV file does not exist.’)
except Exception as e:
raise e
if __name__ == ‘__main__’:
csv_to_json()
我將指出csv_to_json函數(shù)中的一些關(guān)鍵區(qū)域提揍,這些區(qū)域?qū)τ诔晒Φ奶幚碇陵P(guān)重要啤月。
fieldnames = ('day_walked', 'cal_burned', 'miles_walked', 'duration', 'mph', 'shoe_id') - 通過設(shè)置字段名(或列名),我基本上是指定了JSON鍵的內(nèi)容劳跃。
next(csv_reader) - 超過字段名的標(biāo)題行前進(jìn)谎仲,禁止將該行寫入輸出文件。
通過名稱訪問每一列--或者說是鍵刨仑,因?yàn)槲沂褂玫氖荄ictReader--使我能夠?qū)⑺械淖侄晤愋突癁檫m當(dāng)?shù)臄?shù)據(jù)類型(例如郑诺,row['cal_burned'] = float(row['cal_burned'])
json.dump() 方法處理Python對(duì)象的實(shí)際寫入--以及它們轉(zhuǎn)換后的JSON等價(jià)物--到JSON文件中。
現(xiàn)在到了關(guān)鍵時(shí)刻杉武。讓我們調(diào)用 csv_to_json() 函數(shù)辙诞,產(chǎn)生所需的 JSON 文件。
from csv_to_json import csv_to_json
csv_to_json(r’/home/joshua/env_37/dec_2019_hiking_stats.csv’, ‘/home/joshua/env_37/dec_2019_hiking_stats.json’)
帶有類型化的數(shù)據(jù)類型的JSON文件...
Python作為一種語言的便利性是吸引我的眾多因素之一轻抱。用Python操縱CSV數(shù)據(jù)是我最喜歡的功能之一飞涂。而且,由于csv和json模塊被嵌入到語言中祈搜,這兩個(gè)模塊都是現(xiàn)成的较店,不需要第三方的軟件包。
如果您對(duì)這篇文章有任何問題或建議容燕,請(qǐng)隨時(shí)在下面評(píng)論泽西。
Josh Otwell對(duì)研究和成長為一名SQL開發(fā)人員和博客有很大的熱情。他最喜歡的活動(dòng)是把鼻子埋在一本好書缰趋、一篇文章或Linux命令行中捧杉。其中,他喜歡桌面RPG游戲秘血,閱讀幻想小說味抖,并與他的妻子和兩個(gè)女兒共度時(shí)光。
使用PyMySQL灰粮。Python的MySQL庫
用于與MySQL交互的輕量級(jí)Python庫仔涩。
快到周五晚上了,H+S的團(tuán)隊(duì)已經(jīng)準(zhǔn)備好做飯了粘舟。把燈光調(diào)暗熔脂,穿上更舒適的衣服,我們將帶你進(jìn)入這個(gè)100%的有機(jī)風(fēng)味大餐柑肴。今晚的菜單霞揉?一個(gè)Python MySQL庫。PyMySQL晰骑。
PyMySQL是一個(gè)輕量級(jí)的庫适秩,非常適合于簡單的腳本。如果你想連接到一個(gè)MySQL數(shù)據(jù)庫并執(zhí)行一些簡單的查詢,那就不要再找了秽荞。PyMySQL不會(huì)給我們提供像SQLAlchemy這樣的庫所具有的那種花哨的功能骤公,如果我們想建立一個(gè)快速的端點(diǎn),這很好扬跋。PyMySQL的一個(gè)偉大用例是在AWS Lambda(或其他無服務(wù)器功能)中使用阶捆。我們將討論這個(gè)問題,但現(xiàn)在钦听,讓我們來做一些好東西趁猴。
加熱爐子
打開煤氣,準(zhǔn)備好桌子彪见,擺上你最喜歡的盤子系列儡司!這就是我們的工作。這是正確的余指;我們正在談?wù)撃0宀度D阒浪牡絹恚好看文阆胱鲆恍┯行蔚目崾聲r(shí),我們都需要進(jìn)入管理連接和什么的業(yè)務(wù)酵镜。為了減輕痛苦碉碉,我將與你分享一個(gè)處理PyMySQL打開連接的首選方法。
首先淮韭,我們需要?jiǎng)?chuàng)建一個(gè)配置文件垢粮。與SQLAlchemy不同,PyMySQL不支持開箱即用的數(shù)據(jù)庫URI字符串靠粪。正因?yàn)槿绱死桑覀冃枰獮閿?shù)據(jù)庫連接的每個(gè)部分設(shè)置變量,如用戶名占键、密碼等昔善。
"""Config values."""
from os import environ
class Config:
# Database config
db_user = environ.get('DATABASE_USERNAME')
db_password = environ.get('DATABASE_PASSWORD')
db_host = environ.get('DATABASE_HOST')
db_port = environ.get('DATABASE_PORT')
db_name = environ.get('DATABASE_NAME')
""配置值。"""
from os import environ
class Config:
# 數(shù)據(jù)庫配置
我們從一個(gè).env文件中提取這些值:為了安全起見畔乙,我推薦這種做法君仆。
肉和土豆
我將在一個(gè)名為Database的類中包含我們應(yīng)用程序的所有數(shù)據(jù)庫邏輯,以包含與數(shù)據(jù)庫連接有關(guān)的所有變量和函數(shù)牲距。
class Database:
"""Database connection class."""
def __init__(self, config):
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
初始化這個(gè)類將我們的數(shù)據(jù)庫連接變量保存到這個(gè)類的實(shí)例中返咱,同時(shí)創(chuàng)建一個(gè)self.conn變量用于管理連接。我們通過將我們的config對(duì)象傳遞給Database來創(chuàng)建這個(gè)類的實(shí)例牍鞠。
from config import Config
db = Database(config)
在初始化了我們的類之后咖摹,我們就可以開始做飯了。
設(shè)置表
我們將為我們的類添加的第一個(gè)方法將被稱為open_connection()皮服,以管理到我們數(shù)據(jù)庫的連接的打開楞艾。在這里我們?cè)O(shè)置一個(gè)函數(shù),將基本的連接邏輯和錯(cuò)誤信息從我們的應(yīng)用程序中分離出來龄广。
import sys
import pymysql
import logging
class Database:
"""Database connection class."""
...
def open_connection(self):
"""Connect to MySQL Database."""
try:
if self.conn is None:
self.conn = pymysql.connect(self.host,
user=self.username,
passwd=self.password,
db=self.dbname,
connect_timeout=5)
except pymysql.MySQLError as e:
logging.error(e)
sys.exit()
finally:
logging.info('Connection opened successfully.')
輸入sys
數(shù)據(jù)庫連接類
連接到MySQL數(shù)據(jù)庫
嘗試, 如果self.conn是None硫眯。
最后 logging.info('連接成功打開。')
我們看一下我們的類的變量self.conn择同,作為我們的連接對(duì)象两入。通過在類的自我上設(shè)置conn,我們可以讓這個(gè)類的所有方法針對(duì)同一個(gè)數(shù)據(jù)庫連接工作敲才,而不是為每個(gè)查詢打開和關(guān)閉連接裹纳。
openConnection()會(huì)檢查self.conn是否已經(jīng)存在。如果連接不存在紧武,我們的函數(shù)將嘗試用給定的憑證連接到我們的MySQL數(shù)據(jù)庫剃氧。我們?cè)谶@里也有一些邏輯,通過利用PyMySQL內(nèi)置的
pymysql.MySQLError異常類型阻星,在出錯(cuò)時(shí)拋出一個(gè)錯(cuò)誤朋鞍。在與數(shù)據(jù)庫打交道時(shí),習(xí)慣于看到大量的try/except/finally語句妥箕。
現(xiàn)在我們可以在我們類的所有方法之間共享openConnection()滥酥,并且只在需要時(shí)打開連接。
入口
拋開這些無聊的東西畦幢,讓我們來探討一些美好的東西坎吻。我們將從一個(gè)基本的用例開始:從一個(gè)表中選擇所有的行。
class Database:
"""Database connection class."""
def run_query(self, query):
"""Execute SQL query."""
try:
self.open_connection()
with self.conn.cursor() as cur:
records = []
cur.execute(query)
result = cur.fetchall()
for row in result:
records.append(row)
cur.close()
return records
except pymysql.MySQLError as e:
print(e)
finally:
if self.conn:
self.conn.close()
self.conn = None
print('Database connection closed.')
run_query()試圖使用我們先前創(chuàng)建的open_connection()函數(shù)來打開一個(gè)連接宇葱。打開連接后瘦真,我們就可以自由地運(yùn)行我們想要的任何查詢。
我們的函數(shù)被傳遞給一個(gè)叫做query的參數(shù)黍瞧,它代表我們想要運(yùn)行的任何SQL查詢(又稱:SELECT * FROM [table])吗氏。為了執(zhí)行這樣一個(gè)查詢,我們需要打開一個(gè)游標(biāo)雷逆,我們用這一行來做弦讽。
with self.conn.cursor() as cur: ...
當(dāng)cur打開時(shí),我們能夠運(yùn)行所有我們想要的查詢膀哲。讓我們把它提高一個(gè)檔次往产。
選擇數(shù)據(jù)的行數(shù)
現(xiàn)在打開cur,我們可以針對(duì)cur調(diào)用一些方法某宪。
cur.execute([QUERY])
對(duì)cur調(diào)用execute()將在我們的游標(biāo)對(duì)象中運(yùn)行一個(gè)查詢仿村。
cur.fetchall()
在運(yùn)行一個(gè)產(chǎn)生記錄的查詢后,我們可以通過對(duì)cur調(diào)用fetchall()來查看所有由我們的查詢返回的記錄兴喂。正如你所看到的蔼囊,我們應(yīng)該在每個(gè)游標(biāo)上只執(zhí)行一個(gè)查詢焚志。否則,我們就會(huì)重復(fù)寫上一次查詢的結(jié)果畏鼓。試圖打印.fetchall()的結(jié)果酱酬,會(huì)得到一個(gè)整數(shù),代表獲取的行數(shù)云矫。
cur.fetchone()
與fetchall()不同膳沽,fetchone()只獲取我們查詢返回的第一行。如果我們知道只有一條記錄被返回让禀,應(yīng)該
使用.fetchone()
cur.close()
當(dāng)我們最終完成了查詢挑社,我們應(yīng)該用close()關(guān)閉游標(biāo)。
run_query()
假設(shè)我們傳遞的查詢是一個(gè)SELECT查詢巡揍,這就是為什么我們要把結(jié)果保存到一個(gè)數(shù)組中痛阻。如果我們運(yùn)行的是UPDATE或DELETE查詢,這就沒有什么意義了腮敌,因?yàn)槭裁炊疾粫?huì)被返回录平。
更新數(shù)據(jù)的行數(shù)
如果我們不是在選擇數(shù)據(jù),而是在修改它呢缀皱?看看我們的函數(shù)如何變化斗这。
def run_query(self, query):
"""Execute SQL query."""
try:
self.open_connection()
with self.conn.cursor() as cur:
result = cur.execute(query)
self.conn.commit()
affected = f"{cur.rowcount} rows affected."
cur.close()
return affected
conn.commit()
運(yùn)行commit()實(shí)際上是提交了我們查詢中的變化。如果你忘記了這一點(diǎn)啤斗,你的數(shù)據(jù)變化實(shí)際上不會(huì)被保存(這也適用于DELETE和INSERT語句)
cur.rowcount 返回受改變數(shù)據(jù)的查詢影響的行數(shù)表箭。
結(jié)合上述內(nèi)容
所以現(xiàn)在我們有一個(gè)期望SELECT語句的run_query()版本,和一個(gè)期望突變的版本钮莲。我們?cè)鯓硬拍苁惯@個(gè)函數(shù)足夠聰明地處理兩種情況免钻,并返回最合理的結(jié)果呢?在執(zhí)行之前崔拥,檢查一下SELECT這個(gè)詞是否存在于查詢中极舔,怎么樣?
def run_query(self, query):
"""Execute SQL query."""
try:
self.open_connection()
with self.conn.cursor() as cur:
if 'SELECT' in query:
records = []
cur.execute(query)
result = cur.fetchall()
for row in result:
records.append(row)
cur.close()
return records
else:
result = cur.execute(query)
self.conn.commit()
affected = f"{cur.rowcount} rows affected."
cur.close()
return affected
except pymysql.MySQLError as e:
print(e)
finally:
if self.conn:
self.conn.close()
self.conn = None
logging.info('Database connection closed.')
現(xiàn)在链瓦,我們有了一個(gè)可以處理這兩種情況的函數(shù)! 當(dāng)然拆魏,這個(gè)實(shí)現(xiàn)并不是萬無一失的:如果你的某一列恰好命名為SELECT(或其他),你可能會(huì)遇到一些問題慈俯。我想渤刃,不要那樣做。
甜品
希望你能發(fā)現(xiàn)我們的小晚餐約會(huì)是有用的贴膘。如果你正在尋找一些復(fù)制和粘貼的源碼來開始使用我們自己的PyMySQL卖子,請(qǐng)隨時(shí)在Github上查看這個(gè)源代碼。如果這太多了刑峡,請(qǐng)隨意復(fù)制+粘貼下面的內(nèi)容洋闽。
import sys
import pymysql
import logging
class Database:
"""Database connection class."""
def __init__(self, config):
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
def open_connection(self):
"""Connect to MySQL Database."""
try:
if self.conn is None:
self.conn = pymysql.connect(self.host,
user=self.username,
passwd=self.password,
db=self.dbname,
connect_timeout=5)
except pymysql.MySQLError as e:
logging.error(e)
sys.exit()
finally:
logging.info('Connection opened successfully.')
def run_query(self, query):
"""Execute SQL query."""
try:
self.open_connection()
with self.conn.cursor() as cur:
if 'SELECT' in query:
records = []
cur.execute(query)
result = cur.fetchall()
for row in result:
records.append(row)
cur.close()
return records
else:
result = cur.execute(query)
self.conn.commit()
affected = f"{cur.rowcount} rows affected."
cur.close()
return affected
except pymysql.MySQLError as e:
print(e)
finally:
if self.conn:
self.conn.close()
self.conn = None
logging.info('Database connection closed.')
我們感謝你們所有人加入我們這次誘人的冒險(xiǎn)
祝你胃口好玄柠。