通過Python連接到MySQL數(shù)據(jù)庫

通過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ù)有序。

RSJBXViP2N.png

帶有數(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)
祝你胃口好玄柠。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诫舅,隨后出現(xiàn)的幾起案子羽利,更是在濱河造成了極大的恐慌,老刑警劉巖骚勘,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铐伴,死亡現(xiàn)場離奇詭異撮奏,居然都是意外死亡俏讹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門畜吊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泽疆,“玉大人,你說我怎么就攤上這事玲献⊙程郏” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵捌年,是天一觀的道長瓢娜。 經(jīng)常有香客問我,道長礼预,這世上最難降的妖魔是什么眠砾? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮托酸,結(jié)果婚禮上褒颈,老公的妹妹穿的比我還像新娘。我一直安慰自己励堡,他們只是感情好谷丸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著应结,像睡著了一般刨疼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鹅龄,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天币狠,我揣著相機(jī)與錄音,去河邊找鬼砾层。 笑死漩绵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肛炮。 我是一名探鬼主播止吐,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼宝踪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了碍扔?” 一聲冷哼從身側(cè)響起瘩燥,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎不同,沒想到半個(gè)月后厉膀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡二拐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年服鹅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片百新。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡企软,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饭望,到底是詐尸還是另有隱情仗哨,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布铅辞,位于F島的核電站厌漂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏斟珊。R本人自食惡果不足惜苇倡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倍宾。 院中可真熱鬧雏节,春花似錦、人聲如沸高职。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怔锌。三九已至寥粹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間埃元,已是汗流浹背涝涤。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岛杀,地道東北人阔拳。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像类嗤,于是被迫代替她去往敵國和親糊肠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辨宠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容