Successfully reported this slideshow.
Your SlideShare is downloading. ×

資料永續與交換

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 71 Ad
Advertisement

More Related Content

Slideshows for you (20)

Viewers also liked (20)

Advertisement
Advertisement

資料永續與交換

  1. 1. 10. 資料永續與交換 • 學習目標 – 使用 pickle 與 shelve – 認識 DB-API 2.0 – 使用 sqlite3 模組 – 處理 CSV、JSON、XML
  2. 2. 使用 pickle 模組 • 如果要序列化 Python 物件,可以使用內建 的 pickle 模組 • 將一個Python 物件轉換為 bytes,這稱為 Pickling,相反的操作則稱之為 unpickling, 會將 bytes 轉換為 Python 物件
  3. 3. • 若想將物件轉換為 bytes,可以使用 dumps() 函式 • 若想將一個代表物件的 bytes 轉換為物件, 可以使用 loads() 函式
  4. 4. • 可以 pickling 與unpickling 的型態包括內 建型態、使用者自定義的頂層函式、類別 等 • 如果無法進行 pickling 或 unpickling,就 會引發 PicklingError 或 UnpicklingError
  5. 5. • 保存在檔案,從檔案讀取
  6. 6. • pickling 時實際採用的模式,是 Python 的 專屬格式 • pickle 的保證是能向後相容未來的新版本 • 可以使用 pickle.HIGHEST_PROTOCOL 來得知目前可用的最新格式版本為哪一個 • pickle.DEFAULT_PROTOCOL 則是 pickle 模組的預設版本 • 如果必要指定格式版本, • 可以在使用 dumps()、dump()、loads() 或 load() 時,指定其 protocol 參數
  7. 7. 使用 shelve 模組 • shelve 物件行為上像是字典的物件 • 鍵的部份必須是字串,值的部份可以是 pickle 模組可處理的 Python 物件 • 它直接與一個檔案關聯,因此使用上就像 個簡單的資料庫介面
  8. 8. 認識 DB-API 2.0 • DB-API 2.0 由PEP 249 規範,所有的資料 庫介面都應該符合這個規範 • 以便撰寫程式時能有一致的方式,撰寫出 來的程式也便於跨資料庫執行 • Connection 基本上要具備以下的方法:
  9. 9. • Cursor 物件基本上必須具備以下方法:
  10. 10. 使用 sqlite3 模組 • Python 中內建了 SQLite 資料庫,這是個 用 C 語言撰寫的輕量級資料庫 • 資料庫本身的資料可以儲存在一個檔案中, 或者是記憶體之中,後者對於資料庫應用 程式的測試非常的方便 • 若想使用 SQLite 作為資料庫,並撰寫 Python 程式與資料庫進行操作,可以使用 sqlite3 模組
  11. 11. 建立資料庫與連線 • 可以傳給 connect() 一個 ':memory:' 字串,這樣會在記憶體中建立一個資料庫
  12. 12. 建立表格與新增資料
  13. 13. • Connection 物件實作了情境管理器,可 以搭配 with 陳述使用 • 在 with 區塊的動作完成之後,會自動 commit() 與 close(),若發生例外,則 會自動 rollback()
  14. 14. • 若要新增一筆資料,也是使用 Cursor 的 execute()方法
  15. 15. 查詢資料 • 先用 Cursor 的 execute()執行查詢語句 • fetchone() 可以取得結果集合中的一筆 資料 • fetchall()取得結果集合中的全部資料 • fetchmany() 指定要從結果集合中取得幾 筆資料
  16. 16. 更新與刪除資料
  17. 17. 參數化 SQL 語句 • 直接使用 + 來串接字串以組成 SQL,容易 引發 SQL Injection 的安全問題
  18. 18. • 使用字串的 format(),或者是舊式的 % 進行格式化,也會有同樣的問題
  19. 19. • Cursor 的 execute() 方法本身可以將 SQL 語句參數化 • 有兩種參數化的方式:使用問號(?)或具 名佔位符號
  20. 20. • 如果你有多筆 SQL 必須執行,雖然可以使 用 for in 自行處理:
  21. 21. • 用 Cursor 的 executemany() 會更方便:
  22. 22. 簡介交易 • 交易的四個基本: – 要求原子性(Atomicity) – 一致性(Consistency) – 隔離行為(Isolation behavior) – 持續性(Durability) • 依英文字母首字簡稱為 ACID
  23. 23. • 除了一些會隱含地提交之情況,sqlite3 模組的預設實作,並不會自動提交 • 必須自行呼叫 Connection 的 commit() 來進行提交 • 如果交易過程因為發生錯誤或其他情況, 必須撤回交易時,可以呼叫 Connection 的 rollback() 撤回操作
  24. 24. • 一個基於例外發生時必須撤消交易的示範:
  25. 25. • 在隔離性方面,SQLite 資料庫在更新資料 的相關操作時,預設會鎖定資料庫直到該 次交易完成 • 多個連線時就會造成等待的狀況 • sqlite3 模組的 connect() 函式有個 timeout 可指定等待多久,若逾時就引發 例外,預設是 5.0,也就是是 5 秒
  26. 26. • sqlite3 模組的 Connection 物件有個 isolation_level 屬性,可用來設定或 得知目前的隔離性設定 • 預設是'',實際上在 SQLite 資料庫就會產 生 BEGIN 陳述 • 如果 isolation_level 被設置為 None, 表示不做任何的隔離性,也就成為自動提 交,每次 SQL 更新相關操作時,就不用自 行呼叫 Connection 的 commit()方 法
  27. 27. • 不設隔離性,在多個連線存取資料庫的情 況下,就會引發資料不一致的問題 – 更新遺失(Lost update) – 髒讀(Dirty read) – 無法重複的讀取(Unrepeatable read) – 幻讀(Phantom read)
  28. 28. 更新遺失
  29. 29. 髒讀
  30. 30. 無法重複的讀取
  31. 31. 幻讀 • 同一交易期間,讀取到的資料筆數不一致。 例如交易 A 第一次讀取得到五筆資料,此 時交易 B 新增了一筆資料,導致交易 B 再 次讀取得到六筆資料。
  32. 32. • 由於各家資料對於交易的支援程度並不相 同,實際上該採用與如何進行設定也就有 所差異 • 就 sqlite3 模組的實作來說, Connection 物件的 isolation_level 還可以設定 SQLite 資料庫支援的隔離層級 'DEFERRED'、'IMMEDIATE' 或 'EXCLUSIVE'
  33. 33. CSV • 全名為 Comma Separated Values,是通 用在試算表、資料庫間的資料交換格式 • Python 提供了 csv 模組,可隱藏 CSV 的 讀寫細節,讓開發人員輕鬆處理 CSV 格式
  34. 34. • 若想將先前下載的 CSV 檔案轉存為 UTF-8 的話
  35. 35. • 可以使用 csv 的 DictReader()、 DictWriter(),將 CSV 以 dict 的方式 處理
  36. 36. • 使用 fieldnames 自行指定欄位名稱:
  37. 37. • 有一些 dict,想要寫出為CSV:
  38. 38. JSON • 全名 JavaScript Object Notation,為 JavaScript 物件實字 • 可以在〈Introducing JSON〉找到詳細的 JSON 格式說明,以及各語言中可處理 JSON 的程式庫
  39. 39. • 在 Python 中可以使用 dict 與 list 等來 模仿:
  40. 40. • 在 JSON 的物件格式之中: – 名稱必須用 "" 雙引號包括。 – 值可以是 “” 雙引號包括的字串,或者是數字、 true、false、null、JavaScript 陣列(相 當於Python 的 list)或子 JSON 格式
  41. 41. • 數字、true、false、null、使用 "" 包 括的字串等,都是合法的 JSON 格式 • Python 內建了 json 模組,API 的使用上 類似 pickle • 內建型態轉為 JSON 格式的過程稱為編碼 (Encoding) • 將 JSON 格式轉為 Python 內建型態之過程 稱為解碼(Decoding)
  42. 42. • 將 Python 內建型態編碼為 JSON 格式,可 以使用 json.dumps()
  43. 43. • indent 參數可指定數字,這會為JSON 格 式加上指定的空白數量進行縮排:
  44. 44. • seperators 預設是 (', ', ': '),如 果指定為(',', ':'),就不會有空白了 – 像是在資料進行網路傳輸時,若能省掉不必要 的空白,就可省去不必要的流量開銷
  45. 45. • 如果呼叫 json.dump() 時指定了非內建 型態,預設是會引發 TypeError:
  46. 46. • 可以指定一個轉換函式給 default 參數, 轉換函式必須傳回 Python 內建型態,以進 行 JSON 編碼:
  47. 47. • 若要將物件編碼為 JSON 並寫至檔案: • 要將 JSON 格式解碼為內建型態物件:
  48. 48. • 可以在使用 json.loads() 時,指定一個 函式給 object_hook:
  49. 49. • 若要從檔案中讀取 JSON 並解碼:
  50. 50. XML • 在處理XML 時,Python 提供了幾個模組: – xml.dom – xml.sax – xml.etree
  51. 51. • Python 建議 xml.etree.ElementTree • 相對於 DOM 來說,ElementTree 更為簡 單而快速 • 相對於 SAX 來說,也有 iterparse() 可 以使用,可以在讀取 XML 文件的過程中即 時進行處理
  52. 52. • 取得 XML 中全部的標籤名稱:
  53. 53. • 可以使用 fromstring() 來剖析 XML 字 串,這會直接傳回一個 Element 實例,代 表著XML 字串的根節點
  54. 54. • 可以指定 XPath 表示式來取得想要的標籤:
  55. 55. • 想要直接取得 XML 字串的 bytes 資料, 可以使用 tostring():
  56. 56. • 可以使用 append() 來附加一個元素,使 用 insert() 來插入元素,使用 remove() 可以移除元素,使用 set() 設定元素屬性
  57. 57. • 使用 iterparse() 可以針對標籤的 'start'、'end'、'start-ns'、 'end-ns' 事件發生時,進行相對應處理

×