數(shù)據(jù)是怎么存儲在mysql?

我們都知道mysql數(shù)據(jù)庫能存儲大量數(shù)據(jù),但是你知道數(shù)據(jù)是怎么存儲在mysql中的嗎?

數(shù)據(jù)是怎么存儲在mysql?

一般將數(shù)據(jù)保存到MySQL中有兩種方式,同步模式和異步模式。

同步模式

同步模式是采用SQL語句,將數(shù)據(jù)插入到數(shù)據(jù)庫中。但是要注意的是Scrapy的解析速度要遠(yuǎn)大于MySQL的入庫速度,當(dāng)有大量解析的時候,MySQL的入庫就可能會阻塞。

import?MySQLdbclass?MysqlPipeline(object): ????def?__init__(self): ????????self.conn?=?MySQLdb.connect('127.0.0.1','root','root','article_spider',charset="utf8",use_unicode=True) ????????self.cursor?=?self.conn.cursor()????def?process_item(self,?item,?spider): ????????insert_sql?=?""" ????????????insert?into?jobbole_article(title,create_date,url,url_object_id)?VALUES?(%s,%s,%s,%s) ????????""" ????????self.cursor.execute(insert_sql,(item["title"],item["create_date"],item["url"],item["url_object_id"])) ????????self.conn.commit()

異步模式

采用同步模式可能會產(chǎn)生阻塞,我們可以使用Twisted將MySQL的入庫和解析變成異步操作,而不是簡單的execute,commit同步操作。

關(guān)于MySQL的配置,我們可以直接在配置文件配置數(shù)據(jù)庫:

MYSQL_HOST?=?"127.0.0.1" MYSQL_DBNAME?=?"article_spider" MYSQL_USER?=?"root"MYSQL_PASSWORD?=?"root"

在settings中的配置,我們通過在pipeline中定義from_settings獲取settings對象,可以直接獲取settings配置文件中的值。

使用Twisted提供的異步容器連接MySQL:

import?MySQLdb import?MySQLdb.cursorsfrom?twisted.enterprise import?adbapi

使用adbapi可以使mysqldb的一些操作變成異步化的操作
使用cursors進(jìn)行sql語句的執(zhí)行和提交

代碼部分:

class?MysqlTwistedPipline(object): ????def?__init__(self,dbpool): ????????self.dbpool?=?dbpool????@classmethod ????def?from_settings(cls,settings): ????????dbparms?=?dict( ????????????host?=?settings["MYSQL_HOST"], ????????????db???=?settings["MYSQL_DBNAME"], ????????????user?=?settings["MYSQL_USER"], ????????????passwd?=?settings["MYSQL_PASSWORD"], ????????????charset?=?'utf8', ????????????cursorclass?=?MySQLdb.cursors.DictCursor, ????????????use_unicode=True, ????????) ????????dbpool?=?adbapi.ConnectionPool("MySQLdb",**dbparms)????????return?cls(dbpool)????def?process_item(self,?item,?spider): ????????#使用Twisted將mysql插入變成異步執(zhí)行 ????????#runInteraction可以將傳入的函數(shù)變成異步的 ????????query?=?self.dbpool.runInteraction(self.do_insert,item)????????#處理異常 ????????query.addErrback(self.handle_error,item,spider)????def?handle_error(self,failure,item,spider): ????????#處理異步插入的異常 ????????print(failure)????def?do_insert(self,cursor,item): ????????#會從dbpool取出cursor ????????#執(zhí)行具體的插入 ????????insert_sql?=?""" ????????????????????insert?into?jobbole_article(title,create_date,url,url_object_id)?VALUES?(%s,%s,%s,%s) ????????????????""" ????????cursor.execute(insert_sql,?(item["title"],?item["create_date"],?item["url"],?item["url_object_id"]))???????#拿傳進(jìn)的cursor進(jìn)行執(zhí)行,并且自動完成commit操作

以上代碼部分,除了do_insert之外,其它均可復(fù)用。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊9 分享