這篇文章主要介紹了如何讓MySQL數(shù)據(jù)庫(kù)操作更方便,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
成都創(chuàng)新互聯(lián)基于分布式IDC數(shù)據(jù)中心構(gòu)建的平臺(tái)為眾多戶提供遂寧聯(lián)通機(jī)房 四川大帶寬租用 成都機(jī)柜租用 成都服務(wù)器租用。Python的對(duì)MySQL的操作的模塊最好的兩個(gè)模塊是:
1. MySQLdb
這是一個(gè)老牌的MySQL模塊,它封裝了MySQL客戶端的C語(yǔ)言API,但是它主要支持Python 2.x的版本,后來(lái)有人叉了一個(gè)版本加入了Python 3的支持,并起名為mysqlclient -python它的pypi包名為mysqlclient,所以通過(guò)pip安裝就是pip install mysqlclient
2. PyMySQL
這是一個(gè)純Python實(shí)現(xiàn)的MySQL客戶端。因?yàn)槭羌働ython實(shí)現(xiàn),它和Python 3的異步模塊aysncio可以很好的結(jié)合起來(lái),形成了aiomysql模塊,后面我們寫異步爬蟲(chóng)時(shí)就可以對(duì)數(shù)據(jù)庫(kù)進(jìn)行異步操作了。
通過(guò)以上簡(jiǎn)單的對(duì)比,我們選擇了PyMySQL來(lái)作為我們的數(shù)據(jù)庫(kù)客戶端模塊。
我在Python中操作MySQL的時(shí)間已經(jīng)有很年了,總結(jié)下來(lái),還是龍卷風(fēng)里面的那個(gè)torndb的封裝使用比較方便.torndb在Python 2.x時(shí)代早就出現(xiàn)了,那時(shí)候它是對(duì)MySQLdb的封裝。后來(lái)接觸Python 3和PyMySQL,就自己參考torndb和自己的經(jīng)驗(yàn),對(duì)PyMySQL進(jìn)行了一個(gè)封裝,并給它起了個(gè)很土的名字:ezpymysql
不過(guò),這個(gè)很土的名字背后,還是有著讓人省心的方便,希望小猿們能看在它好用的份兒上,別計(jì)較它很土的名字。
廢話不多講,代碼接著上!
首先我們先通過(guò)一個(gè)使用例子看看它的方便性:
from ezpymysql import Connection db = Connection( 'localhost', 'db_name', 'user', 'password' ) # 獲取一條記錄 sql = 'select * from test_table where id=%s' data = db.get(sql, 2) # 獲取多天記錄 sql = 'select * from test_table where id>%s' data = db.query(sql, 2) # 插入一條數(shù)據(jù) sql = 'insert into test_table(title, url) values(%s, %s)' last_id = db.execute(sql, 'test', 'http://a.com/') # 或者 last_id = db.insert(sql, 'test', 'http://a.com/') # 使用更高級(jí)的方法插入一條數(shù)據(jù) item = { 'title': 'test', 'url': 'http://a.com/', } last_id = db.table_insert('test_table', item)
它的使用分兩步:
首先,建立一個(gè)MySQL連接;
然后,通過(guò)sql語(yǔ)句查詢或插入數(shù)據(jù)。
SQLAchemy之類的ORM呢?簡(jiǎn)單說(shuō),就是因?yàn)檫@個(gè)簡(jiǎn)單,我們的操作基本上都是查詢和插入,用基本的選擇,插入這些sql語(yǔ)句是最方便和簡(jiǎn)單的。而ORM要先對(duì)表建立映射模型,查詢方法也是因ORM而不同,過(guò)度的封裝很不適合爬蟲(chóng)應(yīng)用場(chǎng)景。其實(shí),老猿我在寫網(wǎng)絡(luò)應(yīng)用時(shí),仍然是自己寫SQL,感覺(jué)就是那么的清爽!
好吧,不再賣關(guān)子了,該上ezpymysql的實(shí)現(xiàn)了。
#File: ezpymysql.py #Author: veelion """A lightweight wrapper around PyMySQL. only for python3 """ import time import logging import traceback import pymysql.cursors version = "0.7" version_info = (0, 7, 0, 0) class Connection(object): """A lightweight wrapper around PyMySQL. """ def __init__(self, host, database, user=None, password=None, port=0, max_idle_time=7 * 3600, connect_timeout=10, time_zone="+0:00", charset = "utf8mb4", sql_mode="TRADITIONAL"): self.host = host self.database = database self.max_idle_time = float(max_idle_time) args = dict(use_unicode=True, charset=charset, database=database, init_command=('SET time_zone = "%s"' % time_zone), cursorclass=pymysql.cursors.DictCursor, connect_timeout=connect_timeout, sql_mode=sql_mode) if user is not None: args["user"] = user if password is not None: args["passwd"] = password # We accept a path to a MySQL socket file or a host(:port) string if "/" in host: args["unix_socket"] = host else: self.socket = None pair = host.split(":") if len(pair) == 2: args["host"] = pair[0] args["port"] = int(pair[1]) else: args["host"] = host args["port"] = 3306 if port: args['port'] = port self._db = None self._db_args = args self._last_use_time = time.time() try: self.reconnect() except Exception: logging.error("Cannot connect to MySQL on %s", self.host, exc_info=True) def _ensure_connected(self): # Mysql by default closes client connections that are idle for # 8 hours, but the client library does not report this fact until # you try to perform a query and it fails. Protect against this # case by preemptively closing and reopening the connection # if it has been idle for too long (7 hours by default). if (self._db is None or (time.time() - self._last_use_time > self.max_idle_time)): self.reconnect() self._last_use_time = time.time() def _cursor(self): self._ensure_connected() return self._db.cursor() def __del__(self): self.close() def close(self): """Closes this database connection.""" if getattr(self, "_db", None) is not None: self._db.close() self._db = None def reconnect(self): """Closes the existing database connection and re-opens it.""" self.close() self._db = pymysql.connect(**self._db_args) self._db.autocommit(True) def query(self, query, *parameters, **kwparameters): """Returns a row list for the given query and parameters.""" cursor = self._cursor() try: cursor.execute(query, kwparameters or parameters) result = cursor.fetchall() return result finally: cursor.close() def get(self, query, *parameters, **kwparameters): """Returns the (singular) row returned by the given query. """ cursor = self._cursor() try: cursor.execute(query, kwparameters or parameters) return cursor.fetchone() finally: cursor.close() def execute(self, query, *parameters, **kwparameters): """Executes the given query, returning the lastrowid from the query.""" cursor = self._cursor() try: cursor.execute(query, kwparameters or parameters) return cursor.lastrowid except Exception as e: if e.args[0] == 1062: pass else: traceback.print_exc() raise e finally: cursor.close() insert = execute ## =============== high level method for table =================== def table_has(self, table_name, field, value): if isinstance(value, str): value = value.encode('utf8') sql = 'SELECT %s FROM %s WHERE %s="%s"' % ( field, table_name, field, value) d = self.get(sql) return d def table_insert(self, table_name, item): '''item is a dict : key is mysql table field''' fields = list(item.keys()) values = list(item.values()) fieldstr = ','.join(fields) valstr = ','.join(['%s'] * len(item)) for i in range(len(values)): if isinstance(values[i], str): values[i] = values[i].encode('utf8') sql = 'INSERT INTO %s (%s) VALUES(%s)' % (table_name, fieldstr, valstr) try: last_id = self.execute(sql, *values) return last_id except Exception as e: if e.args[0] == 1062: # just skip duplicated item pass else: traceback.print_exc() print('sql:', sql) print('item:') for i in range(len(fields)): vs = str(values[i]) if len(vs) > 300: print(fields[i], ' : ', len(vs), type(values[i])) else: print(fields[i], ' : ', vs, type(values[i])) raise e def table_update(self, table_name, updates, field_where, value_where): '''updates is a dict of {field_update:value_update}''' upsets = [] values = [] for k, v in updates.items(): s = '%s=%%s' % k upsets.append(s) values.append(v) upsets = ','.join(upsets) sql = 'UPDATE %s SET %s WHERE %s="%s"' % ( table_name, upsets, field_where, value_where, ) self.execute(sql, *(values))
這個(gè)實(shí)現(xiàn)是對(duì)pymysql的簡(jiǎn)單封裝,但提供了一些方便的操作:
1.建立MySQL連接
db = Connection( 'localhost', 'db_name', 'user', 'password' )
一般只需要四個(gè)參數(shù)就可以建立連接了:
主持人:數(shù)據(jù)庫(kù)地址,本節(jié)就是本地主機(jī)
database:數(shù)據(jù)庫(kù)名
user:數(shù)據(jù)庫(kù)用戶名
密碼:數(shù)據(jù)庫(kù)用戶的密碼
后面還有幾個(gè)參數(shù)可酌情使用:
max_idle_time:MySQL服務(wù)器默認(rèn)8小時(shí)閑置就會(huì)斷開(kāi)客戶端的連接;這個(gè)參數(shù)告訴客戶端閑置多長(zhǎng)時(shí)間要重新連接;
time_zone:這里默認(rèn)時(shí)區(qū)為0區(qū),你可以設(shè)置為自己的時(shí)區(qū),比如東8區(qū)+8:00;
字符集:默認(rèn)為utf8mb4,即支持門司字符的UTF8;
操作數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)操作分為兩類:讀和寫。
讀操作:使用get()獲取一個(gè)數(shù)據(jù),返回的是一個(gè)dict,key就是數(shù)據(jù)庫(kù)表的字段;使用query()來(lái)獲取一組數(shù)據(jù),返回的是一個(gè)列表,其中每個(gè)項(xiàng)目是一個(gè)dict,跟get()返回的字典一樣。
寫操作:使用insert()或execute(),看源碼就知道,inseret就是執(zhí)的別名。
3.高級(jí)操作
以table_開(kāi)頭的方法:
table_has()查詢某個(gè)值是否存在于表中。查詢的字段最好建立的在MySQL中建立了索引,不然數(shù)據(jù)量稍大就會(huì)很慢。
table_insert()把一個(gè)字典類型的數(shù)據(jù)插入表中。字典的key必須是表的字段。
table_update()更新表中的一條記錄。其中,field_where最好是建立了索引,不然數(shù)據(jù)量稍大就會(huì)很慢。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“如何讓MySQL數(shù)據(jù)庫(kù)操作更方便”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
分享標(biāo)題:如何讓MySQL數(shù)據(jù)庫(kù)操作更方便-創(chuàng)新互聯(lián)
本文鏈接:http://jinyejixie.com/article46/dpshhg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、網(wǎng)站改版、網(wǎng)站排名、外貿(mào)建站、動(dòng)態(tài)網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容