python 数据库表结构转为类_Python数据科学实践 | 数据库1
大家好,基于Python的數(shù)據(jù)科學實踐課程又到來了,大家盡情學習吧。本期內(nèi)容主要由智億同學與政委聯(lián)合推出。
數(shù)據(jù)庫永遠是數(shù)據(jù)管理上最值得使用的工具。而把所收集的大量數(shù)據(jù)放入數(shù)據(jù)庫之后再處理是數(shù)據(jù)科學實踐項目中必不可少的一步。通過前面章節(jié)的學習,我們已經(jīng)掌握了利用Python分析數(shù)據(jù)的眾多模塊,特別地也展示了如何利用爬蟲技術爬取本書中最常使用的火鍋團購數(shù)據(jù)的全過程。本章假設的分析場景是火鍋團購數(shù)據(jù)被爬取后,由于數(shù)據(jù)量過大已經(jīng)進入數(shù)據(jù)庫保存。本章所要講解的內(nèi)容是如何通過Python與數(shù)據(jù)庫交互完成數(shù)據(jù)科學實踐項目。具體內(nèi)容將會通過Python的SQLAIchemy模塊講解。
為什么使用SQLAlchemy?
在回答這個問題之前,得先回答另一個問題:為什么要使用SQL?
試想一下,在第七章網(wǎng)絡爬蟲中,我們直接使用excel、txt和csv文件作為數(shù)據(jù)存儲的載體,這樣做會遇到什么問題?
首先,當數(shù)據(jù)結構非常復雜的時候,無論用excel、txt還是csv,都無法比較良好的維護數(shù)據(jù)結構。比如,以下數(shù)據(jù)結構:
[????(311,?"老北京涮羊肉",?'11:00-21:00',?[['周一',?'滿60減10'],?['周二',?'滿100減20']]),
????(312,?"大龍燚火鍋",?'10:00-22:00',?[['周一',?'滿60減10'],?['周二',?'滿100減20']]),
????(313,?"一尊皇牛",?'00:00-24:00',?[['周一',?'滿80減10'],?['周二',?'滿100減10']]),
]
上面的數(shù)據(jù)結構表示:三家店的店ID、店名、營業(yè)時間、每天的優(yōu)惠活動(這里只為說明問題,列舉兩天)。上面的數(shù)據(jù)結構存在明顯不合理:一家店只有一個店名和營業(yè)時間,只用一行數(shù)據(jù)就可以表示一家店的信息了;但是,一家店會有多個優(yōu)惠活動,這必須要用多行數(shù)據(jù)才可以表示。也就是說,這里的數(shù)據(jù)結構既表示了1對1的關系,也表示了1對N的關系。
此時,店家基本信息和優(yōu)惠活動放在一張表中就明顯不合適了,需要至少兩張表才可以比較好的維護。假如用excel文件,店名必須要輸入N遍(試想一下有20~30個優(yōu)惠券活動,那么店名就得重復輸入至少20次),這非常不方便,而且也不利于數(shù)據(jù)結構的查看。
但是,如果將這個數(shù)據(jù)結構用Python的class實例來表示,就非常容易地能看出數(shù)據(jù)表的結構了:
class?ShopBasic(Base):????#?表的名字:
????__tablename__?=?'basic'
????#?表的結構:
????#?商戶的ID,名字與營業(yè)時間
????id?=?Column(Integer,?primary_key=True,?autoincrement=True)?
????name?=?Column(String(50))
????time?=?Column(String(20),?nullable=True)
class?ShopCoupon(Base):
????#?表的名字:
????__tablename__?=?'coupon'
????#?團購優(yōu)惠的ID,名字,優(yōu)惠時間與對應的商戶的ID
????id?=?Column(Integer,?primary_key=True,?autoincrement=True)
????day?=?Column(String(5))
????coupon?=?Column(String(30))
????#?添加外鍵
????shop_id?=?Column(Integer,?ForeignKey('shopbasic.id'))
其次,當數(shù)據(jù)量比較大的時候,就需要頻繁地對數(shù)據(jù)進行讀取。如果使用excel進行數(shù)據(jù)管理,會十分消耗計算機性能,且大大降低了運行效率。這時候,就需要使用SQL來進行數(shù)據(jù)維護了。
在明白為什么要使用SQL后,就可以回答為什么需要SQLAlchemy了。編寫原生的SQL語句學習成本比較高,如果能有工具可以實現(xiàn)直接用Python語法寫SQL語句的話,豈不美哉!ORM(Object-relational mapping)就是專門為了解決這個問題而創(chuàng)造的,SQLAlchemy就是其中的典型代表。
9.1 初級篇——SQLAlchemy的基本使用在明白為什么需要使用SQLAlchemy后,我們來看看如何使用SQLAlchemy。本章運行環(huán)境為:Python3.5.2,SQLAlchemy1.2.16
9.1.1連接數(shù)據(jù)庫SQLAlchemy支持多種主流的SQL,如PostgreSQL、MySQL、SQLite、Oracle、SQL Server。由于很多嵌入型的應用都自帶SQLite數(shù)據(jù)庫,所以,在讀者看到此書時,很可能電腦上已經(jīng)安裝了這個數(shù)據(jù)庫(沒有安裝的讀者請自行到官網(wǎng)安裝https://www.sqlite.org/download.html)。為方便起見,本書以SQLite對SQLAlchemy進行講解,其他類型的數(shù)據(jù)庫會有細微區(qū)別,使用時根據(jù)提示信息進行查閱即可。
表9.1.1 需要用到的函數(shù)
例9.1.1 示例代碼
import?osfrom?sqlalchemy?import?create_engine
from?sqlalchemy.orm?import?sessionmaker
from?sqlalchemy.ext.declarative?import?declarative_base
#?改成你存放數(shù)據(jù)庫文件的路徑,注意data.db需要提前創(chuàng)建
db_file?=?r'E:\pythonProjects\cluebearpython\chapter11\data'
engine?=?create_engine(name_or_url='sqlite:///{}'.format(os.path.join(db_file,?'data.db')))
DBSession?=?sessionmaker(bind=engine)
#?創(chuàng)建數(shù)據(jù)庫會話實例
sess?=?DBSession()
#?關閉session
sess.close()
在上面的代碼中,由于SQLite是基于文件的數(shù)據(jù)庫,所以,我們需要先data.db。創(chuàng)建data.db后,創(chuàng)建數(shù)據(jù)庫連接,最后創(chuàng)建數(shù)據(jù)庫會話實例,以及會話實例的關閉。注意,由于不同數(shù)據(jù)庫各自的特性,一些參數(shù)是某個或者某幾個數(shù)據(jù)庫獨有的,在這里由于篇幅原因,不一一列舉,讀者視自身需求查閱相關文檔即可。
9.1.2 創(chuàng)建數(shù)據(jù)表第一步展示了如何構建數(shù)據(jù)庫連接并創(chuàng)建數(shù)據(jù)庫會話。在這一步,我們將學習如何創(chuàng)建數(shù)據(jù)表。
表9.1.2 需要用到的函數(shù)?
以本章開篇的兩個數(shù)據(jù)表為例,
例9.1.2?
import?osfrom?sqlalchemy?import?create_engine
from?sqlalchemy.orm?import?sessionmaker,?relationship
from?sqlalchemy.ext.declarative?import?declarative_base
from?sqlalchemy?import?Column,?String,?Integer,?ForeignKey
#?改成你存放數(shù)據(jù)庫文件的路徑,注意data.db需要提前創(chuàng)建
db_file?=?r'E:\pythonProjects\cluebearpython\chapter11\data'
engine?=?create_engine('sqlite:///{}'.format(os.path.join(db_file,?'data.db')),?encoding='utf8')
DBSession?=?sessionmaker(bind=engine)
#?創(chuàng)建數(shù)據(jù)庫會話實例
sess?=?DBSession()
Base?=?declarative_base()
class?ShopBasic(Base):
????#?表的名字:
????__tablename__?=?'basic'
????#?表的結構:
????id?=?Column(Integer,?primary_key=True,?autoincrement=True)
????name?=?Column(String(50))
????time?=?Column(String(20),?nullable=True)
class?ShopCoupon(Base):
????#?表的名字:
????__tablename__?=?'coupon'
????id?=?Column(Integer,?primary_key=True,?autoincrement=True)
????day?=?Column(String(5))
????coupon?=?Column(String(30))
#?會自動檢查表是否存在,如果表不存在,則創(chuàng)建;如果已經(jīng)存在,則忽略,也可以手動注釋,增強可讀性。
Base.metadata.create_all(engine)
在上面的代碼中,截止到創(chuàng)建數(shù)據(jù)庫會話的部分都不變。之后:
1. 先用聲明式方法,顯式關聯(lián)數(shù)據(jù)庫表和Python中的Class對象;
2. 然后讓需要創(chuàng)建或者關聯(lián)的表的類繼承Base對象,每個類中有兩個必須聲明的部分:表的名字,這樣才能讓程序正確關聯(lián)相應的數(shù)據(jù)表;表的字段。如果字段未創(chuàng)建,用Column方法創(chuàng)建字段的相關參數(shù);如果字段已經(jīng)創(chuàng)建,則在Column中指定字段名即可。
3. 最后,調(diào)用Base.metadata.create_all()方法創(chuàng)建以上兩張表。
至此,數(shù)據(jù)表的創(chuàng)建也已經(jīng)完成。通過這種聲明式創(chuàng)建、關聯(lián)表結構的方式,能夠讓我們非常清楚的了解數(shù)據(jù)表的結構,并在此基礎上進行增刪改查。
好了,今天就講到這里。
▼往期精彩回顧▼內(nèi)容索引?|?Python 數(shù)據(jù)科學實踐“京東購買鏈接”
【京東參加每滿100減50的活動 截止到12號】
快進入慕課平臺學習吧總結
以上是生活随笔為你收集整理的python 数据库表结构转为类_Python数据科学实践 | 数据库1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 网关控制家居_在树莓派上搭
- 下一篇: 单纯形法表格法例题详解_优化 |运筹学线