一、數據庫鏈接mysql
# 鏈接配置信息 config = { 'host':'127.0.0.1', 'port':3306, 'user':'root', 'password':'root', 'db':'db', 'charset':'utf8mb4', 'cursorclass':pymysql.cursors.DictCursor, # 遊標設置爲字典類型默認值爲pymysql.cursors.Cursor。 } connection = pymysql.connect(**config) 針對result = cursor.fetchall() : 一、用DictCursor:[{'s_task_model_id': 1}] # 建立遊標,查詢得到的數據以 字典(dict) 形式返回 二、用Cursor時:((1,),) # 返回二維元組 tuple類型 注意:存在中文的時候,鏈接須要添加charset='utf8',不然中文顯示亂碼 Connect()的參數列表: host – 數據庫服務器所在的主機。 user – 登陸用戶名。 password – 登陸用戶密碼。 database – 鏈接的數據庫。 port – 數據庫開放的端口。(默認: 3306) bind_address – 當客戶端有多個網絡接口時,請指定鏈接到主機的接口,參數能夠是主機名或IP地址。 unix_socket – 使用unix套接字而不是tcp/ip。 charset – 鏈接字符集。 sql_mode – 默認SQL模式。 read_default_file – 指定my.cnf文件路徑,以便從[client]部分讀取參數。 conv – 要使用的轉換字典,而不是默認值。 use_unicode – 是否默認爲unicode字符串,對於Py3k,此選項默認爲true。 client_flag – 發送到MySQL的自定義標誌。 cursorclass – 使用自定義的遊標類。 init_command – 創建鏈接時要運行的初始SQL語句。 connect_timeout – 創建鏈接超時時間。(默認: 10,最小: 1,最大: 31536000) read_default_group – 從配置文件中讀取組。 compress – 不支持 named_pipe – 不支持 autocommit – 設置自動提交模式,不設置意味着使用數據庫默認。(默認值: False) local_infile – 是否啓用「LOAD LOCAL INFILE」命令的使用。(默認值: False) max_allowed_packet – 發送到服務器的數據包的最大大小 (以字節爲單位,默認值: 16MB),僅用於限制小於默認值 (16KB) 的 「LOAD LOCAL INFILE」 數據包的大小。 defer_connect – 不要顯式鏈接建設,等待鏈接調用。(默認值: False) auth_plugin_map – A dict of plugin names to a class that processes that plugin. The class will take the Connection object as the argument to the constructor. The class needs an authenticate method taking an authentication packet as an argument. For the dialog plugin, a prompt(echo, prompt) method can be used (if no authenticate method) for returning a string from the user. (experimental) db – 鏈接數據庫別名(兼容MySQLdb) passwd – 密碼輸入別名(兼容MySQLdb) binary_prefix – 在bytes和bytearray上添加_binary前綴(默認: False)
connection對象:web
方法 描述 begin() 開啓事務 commit() 提交事務 cursor(cursor=None) 建立一個遊標用來執行語句 ping(reconnect=True) 檢查鏈接是否存活,會從新發起鏈接 rollback() 回滾事務 close() 關閉鏈接 select_db(db) 選擇數據庫 show_warnings() 查看warning信息
cursor對象:sql
方法 描述 close() 關閉遊標。 execute(query, args=None) 執行單條語句,傳入須要執行的語句,是string類型;同時能夠給查詢傳入參數,參數能夠是tuple、list或dict。執行完成後,會返回執行語句的影響行數,若是有的話。 executemany(query, args) 執行多條INSERT語句,傳入須要執行的語句;同時能夠給查詢傳入參數,參數是一個mappings序列。執行完成後,會返回執行語句的影響行數,若是有的話。 fetchone() 獲取下一行數據。 fetchall() 獲取全部數據。 fetchmany(size=None) 獲取幾行數據。 read_next() 獲取下一行數據。 callproc() 用來調用存儲過程。 mogrify() 參數化查詢,防止SQL注入。 scroll(num,mode) 移動遊標位置。
二、實例數據庫
# fetchone、fetchmany、fetchmany # cursorclass=pymysql.cursors.SSDictCursor # SSCursor遊標類,意在解決數據量大的問題。 cursor = connect.cursor() try: row = cursor.execute(sql) # 返回受影響的行數row # cursor.executemany() 針對一個查詢運行多個數據 數據的格式[('v1','v2'),('v3','v4')] result = cursor.fetchall() # 獲取查詢的全部記錄 結果集是一個對象 result = cursor.fetchmany(n) # 獲取前n條記錄 connect.commit() except: # 若是發生錯誤則回滾 connect.rollback() # 拋出異常緣由 raise finally: connect.close() # 獲取自增id new_id = cursor.lastrowid print(new_id)
三、注入問題flask
excute執行SQL語句的時候,必須使用參數化的方式,不然必然產生SQL注入漏洞 一、一般執行 SQL = "SELECT * FROM scrapy_user_summary WHERE s_username='%s' and s_password_hash='%s'" % (username, password) # 對這條sql注入 username= ' or 1 -- # SELECT * FROM scrapy_user_summary WHERE s_username='' or 1 -- ' and s_password_hash='' # --爲註釋,即無視後續語句 二、用參數化方式,無需在%s兩端加引號 內部執行參數化生成的SQL語句,對特殊字符進行了加\轉義,避免注入語句生成。
四、鏈接池服務器
面對大量的web請求和插入與查詢請求,mysql鏈接會不穩定,針對錯誤’Lost connection to MySQL server during query ([Errno 104] Connection reset by peer)’ 優點:在程序建立鏈接的時候從一個空閒的鏈接中獲取,不須要從新初始化鏈接,提高獲取鏈接的速度 DBUtils是Python的一個用於實現數據庫鏈接池的模塊: mincached,最少的空閒鏈接數,若是空閒鏈接數小於這個數,pool會建立一個新的鏈接。 maxcached,最大的空閒鏈接數,若是空閒鏈接數大於這個數,pool會關閉空閒鏈接。 maxconnections,最大的鏈接數,進程中最大可建立的線程數。 blocking, 當鏈接數達到最大鏈接數時,再次請求時,若是這個值是True,請求鏈接的程序會一直等待,直到當前鏈接數小於最大鏈接數;若是這個值爲False,會報錯。 masxshared,當鏈接數達到這個數時,新請求的鏈接會分享已經分配出去的鏈接。 --------------- # PooledDB :提供線程間可共享的數據庫鏈接,把鏈接放回鏈接池而不是真正的關閉,可重用。 import pymysql from DBUtils.PooledDB import PooledDB pool = PooledDB(pymysql, 5, host="127.0.0.1", user='root', passwd='root', db='scrapy_test', port=3306, charset="utf8") conn = pool.connection() cur = conn.cursor() SQL = "SELECT * FROM scrapy_config" r = cur.execute(SQL) r = cur.fetchall() print(r) cur.close() conn.close() ---------------- # PersistentDB :提供線程專用的數據庫鏈接,線程終止時才真正關閉連接 """ 爲每一個線程建立一個鏈接,經過thread.local實現。 """ from DBUtils.PersistentDB import PersistentDB import pymysql import threading POOL = PersistentDB( creator=pymysql, # 使用連接數據庫的模塊 maxusage=None, # 一個連接最多被重複使用的次數,None表示無限制 setsession=[], # 開始會話前執行的命令列表。如:["set datestyle to ...", "set time zone ..."] ping=0, # ping MySQL服務端,檢查是否服務可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always closeable=False, # 若是爲False時, conn.close() 實際上被忽略,供下次使用,再線程關閉時,纔會自動關閉連接。若是爲True時, conn.close()則關閉連接,那麼再次調用pool.connection時就會報錯,由於已經真的關閉了鏈接(pool.steady_connection()能夠獲取一個新的連接) threadlocal=None, # 本線程獨享值得對象,用於保存連接對象,若是連接對象被重置 host='127.0.0.1', port=3306, user='root', password='', database='flask_demo', charset='utf8' ) def func(): conn = POOL.connection() # conn = SteadyDBConnection() cursor = conn.cursor() cursor.execute('select * from USER WHERE id=1') result = cursor.fetchall() cursor.close() conn.close() # 不是真的關閉,而是假的關閉。 conn = pymysql.connect() conn.close() conn = POOL.connection() # 仍是剛纔使用的鏈接 cursor = conn.cursor() cursor.execute('select * from USER WHERE id=2') result = cursor.fetchall() cursor.close() conn.close() for i in range(10): t = threading.Thread(target=func) t.start()
五、錯誤處理markdown
關於異常見Here 異常 描述 Warning 當有嚴重警告時觸發,例如插入數據是被截斷等等。必須是 StandardError 的子類。 Error 警告之外全部其餘錯誤類。必須是 StandardError 的子類。 InterfaceError 當有數據庫接口模塊自己的錯誤(而不是數據庫的錯誤)發生時觸發。 必須是Error的子類。 DatabaseError 和數據庫有關的錯誤發生時觸發。 必須是Error的子類。 DataError 當有數據處理時的錯誤發生時觸發,例如:除零錯誤,數據超範圍等等。 必須是DatabaseError的子類。 OperationalError 指非用戶控制的,而是操做數據庫時發生的錯誤。例如:鏈接意外斷開、 數據庫名未找到、事務處理失敗、內存分配錯誤等等操做數據庫是發生的錯誤。 必須是DatabaseError的子類。 IntegrityError 完整性相關的錯誤,例如外鍵檢查失敗等。必須是DatabaseError子類。 InternalError 數據庫的內部錯誤,例如遊標(cursor)失效了、事務同步失敗等等。 必須是DatabaseError子類。 ProgrammingError 程序錯誤,例如數據表(table)沒找到或已存在、SQL語句語法錯誤、 參數數量錯誤等等。必須是DatabaseError的子類。 NotSupportedError 不支持錯誤,指使用了數據庫不支持的函數或API等。例如在鏈接對象上 使用.rollback()函數,然而數據庫並不支持事務或者事務已關閉。 必須是DatabaseError的子類。
六、Question網絡
Q:解決存取emoji表情字符? A: 一、修改數據庫字符集character-set-server=utf8mb4 重啓數據庫生效。 二、修改表的字符集爲utf8mb4, alter table character set = utf8mb4