一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Python數(shù)據(jù)存儲(chǔ)讀取,6千字搞定各種方法!

 新用戶0118F7lQ 2022-08-04 發(fā)布于山東
圖片
  • 一、前言

  • 二、專欄概要

  • 三、做準(zhǔn)備:將爬取到的數(shù)據(jù)存入csv和mysql、其他數(shù)據(jù)庫

    • 3.1 前情回顧

    • 3.1 數(shù)據(jù)存入+讀取csv

    • 3.2 數(shù)據(jù)存入+讀取 MySQL

    • 3.3 數(shù)據(jù)存入+讀取 SQLAlchemy

    • 3.4 pandas 自帶to_sql和read_sql實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)、讀取

    • 3.5 其他拓展

  • 四、總結(jié)

一、前言

今天給大家分享的是之前分享過的一篇文章,最近有讀者提起,所以再分享一遍,因?yàn)楹芏嘈伦x者也不會(huì)去翻閱之前分享的文章,所以我就來主動(dòng)推薦給大家閱讀啦~

數(shù)據(jù)獲?。?a target='_blank' textvalue='直接來:一行代碼爬取微博熱搜數(shù)據(jù)' data-itemshowtype='0' tab='innerlink' data-linktype='2' wah-hotarea='click'>直接來:一行代碼爬取微博熱搜數(shù)據(jù)

二、專欄概要

  • 直接來:一行代碼爬取微博熱搜數(shù)據(jù)
  • 做準(zhǔn)備:將爬取到的數(shù)據(jù)存入csv和mysql、其他數(shù)據(jù)庫
  • 搞事情:讀取mysql數(shù)據(jù)并進(jìn)行數(shù)據(jù)分析與可視化
  • 進(jìn)階活:將可視化數(shù)據(jù)結(jié)果呈現(xiàn)到web頁面(大屏可視化)
  • 悄悄話:項(xiàng)目總結(jié)與思考,期待你的來稿

三、做準(zhǔn)備:將爬取到的數(shù)據(jù)存入csv和mysql、其他數(shù)據(jù)庫

首先需要你的電腦安裝好了Python環(huán)境,并且安裝好了Python開發(fā)工具。

如果你還沒有安裝,可以參考以下文章:

如果僅用Python來處理數(shù)據(jù)、爬蟲、數(shù)據(jù)分析或者自動(dòng)化腳本、機(jī)器學(xué)習(xí)等,建議使用Python基礎(chǔ)環(huán)境+jupyter即可,安裝使用參考Windows/Mac 安裝、使用Python環(huán)境+jupyter notebook

如果想利用Python進(jìn)行web項(xiàng)目開發(fā)等,建議使用Python基礎(chǔ)環(huán)境+Pycharm,安裝使用參考 :Windows下安裝、使用Pycharm教程,這下全了Mac下玩轉(zhuǎn)Python-安裝&使用Python/PyCharm

3.1 前情回顧

在上一節(jié)中,我們爬取好了數(shù)據(jù),在之前的基礎(chǔ)上,我拓展了下數(shù)據(jù),爬取了2021年1月1日到2021年9月1日的微博熱搜數(shù)據(jù),需要數(shù)據(jù)的可以在文末獲取,當(dāng)然你直接利用上次獲取數(shù)據(jù)的方法獲取到相應(yīng)數(shù)據(jù),也可以學(xué)習(xí)本系列,不影響。

數(shù)據(jù)基本情況:

Data columns (total 4 columns):
 #   Column         Non-Null Count  Dtype 
---  ------         --------------  ----- 
 0   wb_title       82869 non-null  object
 1   wb_hot_time    82869 non-null  int64 
 2   wb_hot_number  82869 non-null  int64 
 3   wb_first_time  82869 non-null  object
dtypes: int64(2), object(2)
memory usage: 2.5+ MB

字段說明:

字段名數(shù)據(jù)類型含義
wb_titlestr熱搜標(biāo)題
wb_hot_timeint熱搜在榜時(shí)間(分鐘)
wb_hot_numberint熱搜熱度
wb_first_timestr熱搜上榜時(shí)間(第一次)

數(shù)據(jù)示例:圖片

3.1 數(shù)據(jù)存入+讀取csv

這里我們利用pandas的to_csv方法,如果你還沒有安裝過,直接:

pip install pandas

pandas為Python編程語言提供高性能,是基于NumPy 的一種易于使用的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具,pandas為我們提供了高性能的高級(jí)數(shù)據(jù)結(jié)構(gòu)(比如:DataFrame)和高效地操作大型數(shù)據(jù)集所需的工具,同時(shí)提供了大量能使我們快速便捷地處理數(shù)據(jù)的函數(shù)和方法。

首先需要導(dǎo)入pandas模塊,并起一個(gè)別名pd:

import pandas as pd
  • 寫數(shù)據(jù)
# 數(shù)據(jù)已經(jīng)是pandas的DataFrame,所以直接調(diào)用to_csv函數(shù)即可
save_path = '../wb_hot_data.csv'  # 文件存儲(chǔ)路徑,這里使用相對(duì)路徑,存儲(chǔ)到代碼的上級(jí)目錄下
wb_hot_data.to_csv(save_path)

超級(jí)簡單,直接調(diào)用to_scv函數(shù),傳入一個(gè)文件路徑即可實(shí)現(xiàn)寫入csv功能,但是你會(huì)發(fā)現(xiàn)直接打開會(huì)中文會(huì)亂碼,索引列也被存儲(chǔ)進(jìn)去了。圖片

不要急,我在之前寫的數(shù)據(jù)分析從零開始實(shí)戰(zhàn) | 基礎(chǔ)篇(一)有詳細(xì)的to_csv函數(shù)解析,這里直接貼過來,方便大家學(xué)習(xí):

to_csv(path_or_buf,sep,na_rep,columns,header,index)

1. path_or_buf:字符串,文件名、文件具體、相對(duì)路徑、文件流等;

2. sep:字符串,文件分割符號(hào);

3. na_rep:字符串,將NaN轉(zhuǎn)換為特定值;

4. columns:列表,選擇部分列寫入;

5. header:None,寫入時(shí)忽略列名;

6. index:False則選擇不寫入索引,默認(rèn)為True。

我們存儲(chǔ)的時(shí)候設(shè)置下編碼(編碼設(shè)置為utf_8_sig)和不要存儲(chǔ)索引即可:

# 數(shù)據(jù)已經(jīng)是pandas的DataFrame,所以直接調(diào)用to_csv函數(shù)即可
save_path = '../wb_hot_data.csv'  # 文件存儲(chǔ)路徑,這里使用相對(duì)路徑,存儲(chǔ)到代碼的上級(jí)目錄下
# 改為utf_8_sig編碼 https://blog.csdn.net/pipisorry/article/details/44136297
wb_hot_data.to_csv(save_path, encoding='utf_8_sig',index=False)
圖片
  • 讀數(shù)據(jù)
# 直接調(diào)用pandas的read_csv函數(shù)即可,傳入文件存儲(chǔ)路徑
wb_hot_data = pd.read_csv('../wb_hot_data.csv')
# 查看數(shù)據(jù)前3行
wb_hot_data.head(3)

圖片我在之前寫的數(shù)據(jù)分析從零開始實(shí)戰(zhàn) | 基礎(chǔ)篇(一)有詳細(xì)的read_csv函數(shù)解析,這里直接貼過來,方便大家學(xué)習(xí):

read_csv(filepath_or_buffer,sep,header,names,skiprows,na_values,encoding,nrows)
按指定格式讀取csv文件。
常見參數(shù)解析:
1. filepath_or_buffer:字符串,表示文件路徑。

2. sep: 字符串,指定分割符,默認(rèn)是’,’。

3. header:數(shù)值, 指定第幾行作為列名(忽略注解行),如果沒有指定列名,默認(rèn)header=0,數(shù)據(jù)第一行為表頭; 如果指定了列名,則需要設(shè)置header=None。

4. names: 列表,指定列名,如果文件中不包含header的行,應(yīng)該設(shè)置header=None。

5. skiprows:列表,需要忽略的行數(shù)(從0開始),設(shè)置的行數(shù)將不會(huì)進(jìn)行讀取。

6. na_values:列表,設(shè)置需要將值替換成NAN的值,pandas默認(rèn)NAN為缺省,可以用來處理一些缺省、錯(cuò)誤的數(shù)值。

7. encoding:字符串,用于unicode的文本編碼格式。例如,'utf-8''gbk'等文本的編碼格式。

8. nrows:需要讀取的行數(shù)。

直接利用pandas的to_csv和read_csv我們就可以很快的完成python寫、讀csv文件,關(guān)于pandas讀寫其他格式數(shù)據(jù),可以查看我的往期文章:
pandas讀寫csv

pandas讀寫tsv、json

pandas讀寫excel、xml

3.2 數(shù)據(jù)存入+讀取 MySQL

跟著之前的文章安裝好MySQL后(最簡單的安裝方法就是官網(wǎng)下載安裝包然后一步步安裝),就可以進(jìn)行后面操作了。

首先確保mysql安裝和環(huán)境變量配置沒問題,打開終端(或者cmd),輸入下面指令,輸出對(duì)應(yīng)的mysql版本則表示相關(guān)配置ok。

# 1)查看mysql版本 確保環(huán)境變量配置OK
mysql --version
# 2)啟動(dòng)mysql服務(wù)
mysql.server start

接下來,我們需要打開終端(或者cmd),進(jìn)入mysql數(shù)據(jù)庫,并創(chuàng)建一個(gè)數(shù)據(jù)庫sql_study,并在該數(shù)據(jù)庫下創(chuàng)建一張表wb_hot用于存放微博熱搜數(shù)據(jù),主鍵設(shè)置為熱搜標(biāo)題。

當(dāng)然,這些操作也可以利用python完成,這里提前這樣操作是為了讓大家了解mysql基本語法,這對(duì)后面我們使用mysql進(jìn)行數(shù)據(jù)分析處理是有很大好處的,希望你能重視或理解。

# 3)進(jìn)入mysql
mysql -u數(shù)據(jù)庫用戶名 -p設(shè)置的數(shù)據(jù)庫登錄密碼
# 4)創(chuàng)建一個(gè)數(shù)據(jù)庫 sql_study
create database sql_study charset=utf8;
# 5)進(jìn)入數(shù)據(jù)庫
use sql_study;
# 6)創(chuàng)建一個(gè)數(shù)據(jù)表 wb_hot
create table if not exists `wb_hot`(
`wb_title` varchar(100) not null,
`wb_hot_time` int not null,
`wb_hot_number` int not null,
`wb_first_time` datetime not null,
primary key(`wb_title`, `wb_first_time`)
)engine=InnoDB default charset=utf8;
# 7)查看新建的表
show tables;

接下來我們使用pymysql這個(gè)庫來實(shí)現(xiàn)Python對(duì)mysql的操作,首先安裝pymysql,推薦直接使用鏡像源安裝,速度快,

pip install -i https://pypi.douban.com/simple/ pymysql

打開jupyter notebook,開始寫代碼啦~(當(dāng)然你習(xí)慣用其他開發(fā)工具也可以,如pycharm、vscode等)

# 打開jupyter
jupyter notebook

這里我們假設(shè)數(shù)據(jù)已經(jīng)讀取出來,存放在 wb_hot_data 一個(gè)dataframe對(duì)象,你可以是直接接上一篇文章爬取數(shù)據(jù)整理后,或者是本篇文章中從 csv文件讀取都可以,總之我們假設(shè)數(shù)據(jù)已經(jīng)讀取到了 wb_hot_data 變量中,后面也是。

數(shù)據(jù)已經(jīng)準(zhǔn)備好了,我們就開始利用python連接mysql并進(jìn)行相關(guān)插入操作吧~

  • 連接mysql
import pymysql

# 連接數(shù)據(jù)庫 并添加cursor游標(biāo),后面所有操作都利用游標(biāo)進(jìn)行
conn = pymysql.connect(host = 'localhost',port = 3306,user = '你的數(shù)據(jù)庫登錄用戶名', password = '你的數(shù)據(jù)庫登錄密碼',charset='utf8')
cursor = conn.cursor()
  • 創(chuàng)建數(shù)據(jù)庫
'''
新建一個(gè)數(shù)據(jù)庫
database:數(shù)據(jù)庫名稱
cursor:數(shù)據(jù)庫連接游標(biāo)
'''

def create_database(database, cursor):
    # 創(chuàng)建database, 如果存在則不創(chuàng)建
    cursor.execute('create database if not exists %s;'%database)
    # 將相關(guān)操作內(nèi)容傳入數(shù)據(jù)庫
    conn.commit()
    print('成功創(chuàng)建數(shù)據(jù)庫:%s'%database)
  • 指定數(shù)據(jù)庫中創(chuàng)建數(shù)據(jù)表
'''
在指定數(shù)據(jù)庫中新建一個(gè)數(shù)據(jù)表
'''

def create_table(table_name, table_sql, database, cursor):
    # 選擇 database 數(shù)據(jù)庫
    cursor.execute('use %s;'%database)
    # 創(chuàng)建數(shù)據(jù)表,因?yàn)閿?shù)據(jù)表創(chuàng)建相對(duì)復(fù)雜,所以直接傳入sql語句
    cursor.execute(table_sql)
    # 將相關(guān)操作內(nèi)容傳入數(shù)據(jù)庫
    conn.commit()
    print('成功在數(shù)據(jù)庫{0}中創(chuàng)建數(shù)據(jù)表:{1}'.format(database,table_name))
  • 對(duì)指定數(shù)據(jù)表進(jìn)行增刪查改
'''
在指定數(shù)據(jù)庫的數(shù)據(jù)表中增、刪、查、改
'''

def sql_basic_operation(table_sql, database, cursor):
    # 選擇 database 數(shù)據(jù)庫
    cursor.execute('use %s'%database)
    # 執(zhí)行sql語句
    cursor.execute(table_sql)
    # 增刪查改 一般為批量操作,不建議直接commit,可以操作完自己寫個(gè)commit
    # 這樣執(zhí)行效率會(huì)高很多,實(shí)測8w+數(shù)據(jù),先插入所有再commit的耗費(fèi)17.48s
    # 每插入一次就commit一次的耗時(shí)為56.63s
    # conn.commit()
    print('sql語句執(zhí)行成功')

從上面我們可以看出,主要是利用了execute函數(shù)來執(zhí)行sql操作語句,從而實(shí)現(xiàn)對(duì)數(shù)據(jù)庫的控制。

利用python將爬取到的數(shù)據(jù)存入mysql

由于數(shù)據(jù)庫和數(shù)據(jù)表我們之前已經(jīng)創(chuàng)建過了,所以現(xiàn)在只需要插入數(shù)據(jù)到mysql即可,接下來我們寫一個(gè)循環(huán)插入數(shù)據(jù)的語句吧~

'''
將dataframe數(shù)據(jù)存儲(chǔ)到mysql
'''

import time
def df_to_sql(df, table_name, database, cursor):
    t1 = time.time()  # 時(shí)間戳 單位秒
    print('數(shù)據(jù)插入開始時(shí)間:{0}'.format(t1))
    i = 0
    for row in df.itertuples():
        # print(type(row))  # <class 'pandas.core.frame.Pandas'>
        # 拼接插入sql語句
        # insert into wb_hot values('謝允妻管嚴(yán)', 142, 276514, '2021-01-01 16:59:00');
        sql_insert = '''insert into {0} values('{1}', {2}, {3}, '{4}');
        '''
.format(table_name,getattr(row,'wb_title'), 
                   getattr(row,'wb_hot_time'), 
                   getattr(row,'wb_hot_number'), 
                   getattr(row,'wb_first_time')
                  )   
        # 將插入語句傳入函數(shù),執(zhí)行相關(guān)操作
        sql_basic_operation(sql_insert, database, cursor)
        i+=1
    conn.commit()
    t2 = time.time()  # 時(shí)間戳 單位秒
    print('數(shù)據(jù)插入結(jié)束時(shí)間:{0}'.format(t2))
    print('成功插入數(shù)據(jù)%d條,'%i, '耗費(fèi)時(shí)間:%.5f秒。'%(t2-t1))    

接著我們就可以將數(shù)據(jù)插入mysql數(shù)據(jù)庫啦,

# 對(duì)數(shù)據(jù)進(jìn)行小處理,將wb_first_time列改為日期類型
wb_hot_data['wb_first_time'] = pd.to_datetime(wb_hot_data['wb_first_time'])

df_to_sql(wb_hot_data, 'wb_hot''sql_study', cursor)

圖片一共82869條數(shù)據(jù),從mysql后臺(tái)也可以看到相關(guān)數(shù)據(jù),都正常。圖片

利用python從mysql讀取爬取到的數(shù)據(jù)

根據(jù)上面學(xué)習(xí),我們直接寫好讀?。ú樵儯┑膕ql語句就可以啦,然后調(diào)用我們之前寫的sql操作函數(shù)即可讀取相關(guān)數(shù)據(jù):

'''
從sql讀取數(shù)據(jù),并轉(zhuǎn)成dataframe格式數(shù)據(jù)
'''

def read_from_sql(sql_query, database, cursor, columns):
    # 直接調(diào)用
    sql_basic_operation(sql_query, database, cursor)
    conn.commit()
    # 獲取匹配到的數(shù)據(jù)
    result = cursor.fetchall()  # 放回?cái)?shù)據(jù)為元組 格式((字段名1, 字段名2...),()...)
    # 將元組數(shù)據(jù)轉(zhuǎn)為dataframe
    df = pd.DataFrame(result, columns=columns)
    return df

調(diào)用數(shù)據(jù)查詢函數(shù),并獲取相關(guān)數(shù)據(jù):

'''
獲取wb_hot中前三行數(shù)據(jù)
'''

# sql查詢語句
sql_query = '''select * from wb_hot limit 3'''
# 列名
columns = ['wb_title''wb_hot_time''wb_hot_number''wb_first_time']
# 調(diào)用函數(shù),并獲取返回值
sql_data = read_from_sql(sql_query, 'sql_study', cursor, columns)  
sql_data

圖片我們會(huì)發(fā)現(xiàn)這與我們存入數(shù)據(jù)的前三行不同,這是因?yàn)樵趍ysql中插入數(shù)據(jù)默認(rèn)會(huì)按主鍵順序進(jìn)行排列,解決這個(gè)問題最好的方法是我們家一個(gè)自增序號(hào)列,并設(shè)置為主鍵,這樣數(shù)據(jù)順序就和我們插入順序一致了。

或者我們在寫查詢語句加上指定的查詢條件(where),以及排序列(order by)即可。

# 完成操作后記得close cursor和conn
cursor.close()
conn.close()

3.3 數(shù)據(jù)存入+讀取 SQLAlchemy

SQLAlchemy 是 Python SQL 工具包和對(duì)象關(guān)系映射器(ORM),可為應(yīng)用程序開發(fā)人員提供 SQL 的全部功能和靈活性。所謂ORM,就是指把關(guān)系數(shù)據(jù)庫的表結(jié)構(gòu)映射到對(duì)象上,在Python里面我們直接操作對(duì)象,就能對(duì)數(shù)據(jù)庫進(jìn)行操作了,簡便、邏輯性更強(qiáng)。

首先還是安裝SQLAlchemy模塊:

pip install -i https://pypi.douban.com/simple/ sqlalchemy

3.3.1 首先導(dǎo)入相關(guān)包

# 導(dǎo)入相關(guān)包
from sqlalchemy import Column, String, Integer, DateTime, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

sqlalchemy下的:

  • Column 數(shù)據(jù)列對(duì)象
  • String, Integer, DateTime 數(shù)據(jù)類型
  • create_engine 創(chuàng)建數(shù)據(jù)庫連接引擎,有個(gè)重要參數(shù)url,一般格式為:數(shù)據(jù)庫類型+數(shù)據(jù)庫驅(qū)動(dòng)://數(shù)據(jù)庫用戶名:數(shù)據(jù)庫密碼@IP地址:端口/數(shù)據(jù)庫

sqlalchemy.orm下的:

  • sessionmaker 創(chuàng)建python與數(shù)據(jù)庫的會(huì)話對(duì)象,后面直接利用實(shí)例化session對(duì)象調(diào)用增刪查改相關(guān)操作

sqlalchemy.ext.declarative下的:

  • declarative_base 創(chuàng)建sqlalchemy基本對(duì)象,很重要

3.3.2 初始化數(shù)據(jù)庫,并創(chuàng)建會(huì)話session

# 初始化數(shù)據(jù)庫連接引擎
# create_engine('數(shù)據(jù)庫類型+數(shù)據(jù)庫驅(qū)動(dòng)://數(shù)據(jù)庫用戶名:數(shù)據(jù)庫密碼@IP地址:端口/數(shù)據(jù)庫',其他參數(shù))
engine = create_engine('mysql+pymysql://數(shù)據(jù)庫用戶名:數(shù)據(jù)庫密碼@localhost:3306/sql_study?charset=utf8')
# 創(chuàng)建數(shù)據(jù)庫會(huì)話對(duì)象,并實(shí)例化
db_session = sessionmaker(bind=engine)()

3.3.3 創(chuàng)建一個(gè)WbHot類,并利用WbHot類創(chuàng)建表wb_hot

# 創(chuàng)建sqlalchemy基本對(duì)象
# 后面每個(gè)對(duì)象都繼承自它
Base = declarative_base()

# 定義WbHot類,一個(gè)類可以理解成一張表
# 后面對(duì)對(duì)象進(jìn)行操作就是對(duì)表進(jìn)行操作
class WbHot(Base):
    # 表名,為了不和之前的表重名,新表起名為wb_hot2
    __tablename__ = 'wb_hot2'

    # 表結(jié)構(gòu),初學(xué)者對(duì)照sql創(chuàng)建語句寫更簡單
    '''
    create table if not exists `wb_hot`(
        `wb_title` varchar(100) not null,
        `wb_hot_time` int not null,
        `wb_hot_number` int not null,
        `wb_first_time` datetime not null,
        primary key(`wb_title`, `wb_first_time`)
    )engine=InnoDB default charset=utf8;
    '''

    # Column nullable是否可為空 primary_key 是否為主鍵
    wb_title = Column(String(100), nullable=False, primary_key=True)
    wb_hot_time = Column(Integer, nullable=False)
    wb_hot_number = Column(Integer, nullable=False)
    wb_first_time = Column(DateTime, nullable=False, primary_key=True)
    

# 調(diào)用基礎(chǔ)對(duì)象中的元數(shù)據(jù)模塊中的create_all創(chuàng)建數(shù)據(jù)表
Base.metadata.create_all(engine)

創(chuàng)建好表,我們可以在mysql下查看下我們剛剛創(chuàng)建的表相關(guān)信息,可以看出,和之前直接利用sql創(chuàng)建的數(shù)據(jù)表表結(jié)構(gòu)一致。圖片

3.3.4 存儲(chǔ)數(shù)據(jù)

表創(chuàng)建好后,我們就可以開始存儲(chǔ)數(shù)據(jù)啦,前面說過了,sqlalchemy是對(duì)對(duì)象進(jìn)行操作了,所以我們將數(shù)據(jù)變成一個(gè)一個(gè)的WbHot對(duì)象,然后在調(diào)用session中的add函數(shù)即可實(shí)現(xiàn)新增數(shù)據(jù),代碼如下:

# 存儲(chǔ)數(shù)據(jù)
import time
def sqlalchemy_to_sql(df, session):
    t1 = time.time()  # 時(shí)間戳 單位秒
    print('數(shù)據(jù)插入開始時(shí)間:{0}'.format(t1))
    i = 0
    for row in df.itertuples():
        # print(type(row))  # <class 'pandas.core.frame.Pandas'>
        # 初始化WbHot對(duì)象
        # WbHot('謝允妻管嚴(yán)', 142, 276514, '2021-01-01 16:59:00');
        wb_hot = WbHot(wb_title=getattr(row,'wb_title'), 
                   wb_hot_time=getattr(row,'wb_hot_time'), 
                   wb_hot_number=getattr(row,'wb_hot_number'), 
                   wb_first_time=getattr(row,'wb_first_time')
                  )   
        # 調(diào)用session中的add函數(shù)將對(duì)象添加到數(shù)據(jù)表
        session.add(wb_hot)
        i+=1
    session.commit()
    t2 = time.time()  # 時(shí)間戳 單位秒
    print('數(shù)據(jù)插入結(jié)束時(shí)間:{0}'.format(t2))
    print('成功插入數(shù)據(jù)%d條,'%i, '耗費(fèi)時(shí)間:%.5f秒。'%(t2-t1))
        
# 調(diào)用函數(shù)  
sqlalchemy_to_sql(wb_hot_data, db_session) 

sql里還提供了一種一直新增多行數(shù)據(jù)的方法add_all,將所有要提交的數(shù)據(jù)存入列表,然后利用session調(diào)用add_all函數(shù)即可,測試了下,以8w條數(shù)據(jù)為例,兩者效率如下:

add 成功插入數(shù)據(jù)82869條, 耗費(fèi)時(shí)間:8.07842秒。
add_all 成功插入數(shù)據(jù)82869條, 耗費(fèi)時(shí)間:7.29939秒。

相差0.8s左右,當(dāng)然會(huì)有誤差,不過不管怎么說,這比前面直接用pymysql使用sql語句插入數(shù)據(jù)的效率高了2倍多,優(yōu)秀~

3.3.4 讀取(查詢)數(shù)據(jù)

這里我們直接調(diào)用query函數(shù)進(jìn)行查詢,這個(gè)函數(shù)功能非常強(qiáng)大,包含了很多查詢方法,比如:limit、filter、order_by、group_by等,操作起來非常方便。

def wbhot_to_df(data, columns):
    df_data = []
    for i in data:
        list_data = [i.wb_title, i.wb_hot_time, i.wb_hot_number, i.wb_first_time]
        df_data.append(list_data)
    df = pd.DataFrame(df_data, columns=columns)
    return df

# 讀取非常簡單,直接調(diào)用query函數(shù)即可
# all()表示 所有查詢到的數(shù)據(jù)對(duì)象
# first()表示 查詢到的數(shù)據(jù)對(duì)象中的第一個(gè)
data = db_session.query(WbHot).limit(3).all()
columns = ['wb_title''wb_hot_time''wb_hot_number''wb_first_time']
# 調(diào)用函數(shù),將批量WbHot對(duì)象轉(zhuǎn)換成dataframe
data_df = wbhot_to_df(data, columns)
圖片

接下來我們簡單介紹下sqlalchemy中查詢的一些幾本操作(以WbHot類為例):

# 直接查詢,并返回所有數(shù)據(jù),返回為一個(gè)包含WbHot的列表
db_session.query(WbHot).all()

# 限制輸出列 limit
# 查詢所有數(shù)據(jù),輸出前五行
db_session.query(WbHot).limit(5).all()

# 單條件過濾查詢 返回所有熱搜在榜時(shí)間2h及以上的熱搜數(shù)據(jù)
# filter參數(shù) 類名.字段名 
db_session.query(WbHot).filter(WbHot.wb_hot_time>=120).all()

# 多條件過濾查詢 
# filter_by 不能使用判斷過濾,比如== >=等,另外參數(shù)是字段名,不需要類名.字段名
db_session.query(WbHot).filter_by(wb_hot_time=528 , wb_hot_number=2995191).all()

# 也可以使用filter來進(jìn)行多條件過濾,略麻煩
# 需要從sqlalchemy導(dǎo)入 and_, or_(與、或判斷方法)
# 返回所有熱搜在榜時(shí)間2h及以上且熱度大于1千萬的數(shù)據(jù)
from sqlalchemy import and_, or_
db_session.query(WbHot).filter(and_(WbHot.wb_hot_time>=120, WbHot.wb_hot_number>=10000000)).all()

# 查詢結(jié)果排序 order_by 
# 參數(shù) 類名.字段名[.desc() 降序|asc() 升序]
# 返回所有熱搜在榜時(shí)間2h及以上且熱度大于3千萬的數(shù)據(jù),按熱度降序排序
from sqlalchemy import and_, or_
db_session.query(WbHot).filter(and_(WbHot.wb_hot_time>=120, WbHot.wb_hot_number>=30000000)).order_by(WbHot.wb_hot_number.desc()).all()



# 分組查詢 order_by
# 參數(shù) 類名.字段名
# 按標(biāo)題分組,計(jì)算每個(gè)標(biāo)題出現(xiàn)的天數(shù)、總在線時(shí)長、總熱度、最后在線時(shí)間
db_session.query(WbHot.wb_title, 
            func.count(WbHot.wb_title).label('counts'),
            func.sum(WbHot.wb_hot_time).label('wb_hot_times'), 
            func.sum(WbHot.wb_hot_number).label('wb_hot_numbers'), 
            func.max(WbHot.wb_first_time).label('wb_finally_time')).group_by(WbHot.wb_title).having(func.count(WbHot.wb_title)>=10).all()

更多其他關(guān)于sqlalchemy查詢數(shù)據(jù)庫用法,大家用到的時(shí)候?yàn)g覽器一查就可以啦~也歡迎大家留言區(qū)補(bǔ)充。

除了mysql數(shù)據(jù)庫外,sqlalchemy也可以連接很多其他數(shù)據(jù)庫,如:

# '數(shù)據(jù)庫類型+數(shù)據(jù)庫驅(qū)動(dòng)名稱://用戶名:密碼@機(jī)器地址:端口號(hào)/數(shù)據(jù)庫名'
engine = create_engine('sqlite:/// wb_hot.db'# 連接sqlite文件
engine = create_engine('postgresql://用戶名:密碼@hostname:5432/dbname')  # 連接postgresql
engine = create_engine('oracle://用戶名:密碼@hostname:1521/sidname'# oracle  # 連接oracle
...

3.4 pandas 自帶to_sql和read_sql實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)、讀取

3.4.1 to_sql 存儲(chǔ)數(shù)據(jù)到mysql

經(jīng)過實(shí)驗(yàn),這種方法寫數(shù)據(jù)效率是最高的,直接上代碼,

# 調(diào)用pandas 的 to_sql 存儲(chǔ)數(shù)據(jù)
import time
from sqlalchemy import create_engine
# 利用sqlalchemy的create_engine創(chuàng)建一個(gè)數(shù)據(jù)庫連接引擎
engine = create_engine('mysql+pymysql://用戶名:密碼@localhost:3306/sql_study?charset=utf8')
t1 = time.time()  # 時(shí)間戳 單位秒
print('數(shù)據(jù)插入開始時(shí)間:{0}'.format(t1))
# 直接調(diào)用to_sql
# 第一個(gè)參數(shù):表名,如果表不存在就會(huì)直接根據(jù)數(shù)據(jù)結(jié)構(gòu)新建
# 第二個(gè)參數(shù):engine,數(shù)據(jù)庫連接引擎
# 第三個(gè)參數(shù):設(shè)置存儲(chǔ)不要將數(shù)據(jù)索引存入
# 第四個(gè)參數(shù):如果表存在,以什么方式存儲(chǔ),append表示追加,replace表示刪除表重建,默認(rèn)fail拋出ValueError異常
wb_hot_data.to_sql('wb_hot2', engine, index=False, if_exists='append')
t2 = time.time()  # 時(shí)間戳 單位秒
print('數(shù)據(jù)插入結(jié)束時(shí)間:{0}'.format(t2))
print('成功插入數(shù)據(jù)%d條,'%len(wb_hot_data), '耗費(fèi)時(shí)間:%.5f秒。'%(t2-t1))

圖片僅僅花了2.4s,比pymysql快9倍,比sqlalchemy快4倍,當(dāng)然也可能是我操作問題(pymysql、sqlalchemy里我都寫了循環(huán),一個(gè)個(gè)讀取然后再存入,遍歷本生會(huì)耗費(fèi)很長時(shí)間),如果大家有更好方法,歡迎留言區(qū)分享。

3.4.2 read_sql 讀取數(shù)據(jù)從mysql

# 讀取的sql語句
sql = 'select * from wb_hot2'
# 第一個(gè)參數(shù):查詢sql語句
# 第二個(gè)參數(shù):engine,數(shù)據(jù)庫連接引擎
# 第三個(gè)參數(shù):將指定列轉(zhuǎn)換成指定的日期格式
pd_read_sql = pd.read_sql(sql, engine, parse_dates={'wb_first_time''%Y:%m:%H:%M:%S'})

圖片簡單便捷,讀取出來的數(shù)據(jù)格式也都對(duì),而且就是dataframe數(shù)據(jù)格式,更方便我們進(jìn)行數(shù)據(jù)分析和處理。

我還發(fā)現(xiàn)這個(gè)read_sql還可以執(zhí)行復(fù)雜的查詢,效率也還比較高,如查詢熱搜熱度在3千萬以上且在榜時(shí)間超過2h的熱搜數(shù)據(jù):

sql = 'select * from wb_hot2 where wb_hot_number>=30000000 and wb_hot_time>120'
pd_read_sql = pd.read_sql(sql, engine, parse_dates={'wb_first_time''%Y:%m:%H:%M:%S'})

簡直太香了,我覺定后面就用pandas+sqlalchemy了。

3.5 其他拓展

在之前的文章由詳細(xì)介紹postgresql數(shù)據(jù)庫,里面有詳細(xì)介紹sqlalchemy與postgresql交互操作,大家可以去看看,點(diǎn)擊前往學(xué)習(xí),同時(shí)里面也介紹了python連接mysql mongodb sqlite的部分,這里貼過來方便大家學(xué)習(xí)。

mongodb
Python連接mongodb使用pymongodb即可,連接操作也很簡單,直接在開啟mongodb服務(wù)后,pymongo.MongoClient(host='127.0.0.1',port=27017)連接即可,默認(rèn)端口是27017。

# 使用前先安裝 pymongodb 模塊 :pip install pymongodb 
# 導(dǎo)入 pymogodb 模塊
import pymongo
# 連接數(shù)據(jù)庫,參數(shù)說明:服務(wù)器IP,端口號(hào)默認(rèn)為27017
my_client = pymongo.MongoClient(host='127.0.0.1',port=27017)
# 直接通過數(shù)據(jù)庫名稱索引,有點(diǎn)像字典
my_db = my_client['db_name']  
# 連接 collection_name 集合,Mongodb里集合就相當(dāng)于Mysql里的表
my_collection = my_client['collection_name']  
datas = my_collection .find() # 查詢
for x in datas :
  print(x)

sqlite
除了上面提到的用sqlachemy操作sqlite,還可以直接利用sqlite3這個(gè)模塊操作,連接也非常方便,sqlite3.connect('test.db')直接傳入sqlite數(shù)據(jù)文件目錄即可。

# 使用前先安裝 sqlite3  模塊 :pip install sqlite3
'''
sqlite數(shù)據(jù)庫和前面兩種數(shù)據(jù)庫不一樣,它是一個(gè)本地?cái)?shù)據(jù)庫
也就是說數(shù)據(jù)直接存在本地,不依賴服務(wù)器
'''

# 導(dǎo)入 sqlite3 模塊
import sqlite3
# 連接數(shù)據(jù)庫,參數(shù)說明:這里的參數(shù)就是數(shù)據(jù)文件的地址
conn = sqlite3.connect('test.db')
#使用cursor()方法創(chuàng)建一個(gè)游標(biāo)對(duì)象
c = conn.cursor()
#使用execute()方法執(zhí)行SQL語句
cursor = c.execute('SELECT * from test_table')
for row in cursor:
  print(row)
#關(guān)閉游標(biāo)和數(shù)據(jù)庫的連接
c.close()
conn.close()

四、總結(jié)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    国产精品久久精品国产| 日韩精品人妻少妇一区二区| 亚洲av秘片一区二区三区| 国产一区二区久久综合| 精品al亚洲麻豆一区| 久久福利视频在线观看 | 大香蕉网国产在线观看av| 国内九一激情白浆发布| 亚洲成人免费天堂诱惑| 日韩av欧美中文字幕| 欧美黄色成人真人视频| 精品老司机视频在线观看| 小黄片大全欧美一区二区| 日本丁香婷婷欧美激情| 欧美韩国日本精品在线| 中文字幕高清免费日韩视频| 五月天丁香婷婷一区二区| 91偷拍裸体一区二区三区| 精品al亚洲麻豆一区| 亚洲中文字幕三区四区| 日韩精品一区二区三区av在线| 日本东京热视频一区二区三区| 国产又粗又硬又长又爽的剧情| 国产女同精品一区二区| 小黄片大全欧美一区二区| 久久女同精品一区二区| 麻豆蜜桃星空传媒在线观看| 久久国产青偷人人妻潘金莲| 日韩精品第一区二区三区| 亚洲国产av国产av| 欧美黑人在线一区二区| 91亚洲国产成人久久| 免费在线成人激情视频| 国产精品日韩精品最新| 中文字幕av诱惑一区二区| 夫妻性生活黄色录像视频| 国产成人精品国产成人亚洲| 婷婷激情五月天丁香社区 | 午夜福利黄片免费观看| 欧美一区二区三区性视频| 狠狠亚洲丁香综合久久|