Python SQLAlchemy --1
本文為 Python SQLAlchemy ORM 一系列教學文:
SQLAlchemy 大概是目前 Python 最完整的資料庫操作的套件了,不過最令人垢病的是它的文件真的很難閱讀,如果不搭配個實例進行學習真的很難理解。
此外,SQLAlchemy 依照架構將文件說明分為 SQLAlchemy ORM
與 SQLAlchemy Core
,如果不去細究到底有何不同,很容易讓人誤解。
基本上,如果只是基本的資料庫的表格建立、查詢、更新、刪除等,比較不需要使用表格間的關聯以及表格與 Python 表格物件關聯的話,其實用 SQLAlchemy Core
就足以應付需求了;但是想追求優雅的解決方案,同時又需要兼顧多表格之間的關聯的話,建議使用 SQLAlchemy ORM
。
事實上,從 SQLAlchemy 的架構圖來看, SQLAlchemy ORM
相較於 SQLAlchemy Core
而言是高層次的功能,因此學會 SQLAlchemy ORM
的話,絕對是猶如神器在手,所向披靡。
接下來就用幾個範例實際來說明 SQLAlchemy ORM
的使用吧。
安裝
- 本文以 Linux 環境為主
- 需安裝 Python 3 以上
- 需安裝 Python setuptools (連結)
- 以 SQLAlchemy 1.0.15 為主
安裝 SQLAlchemy 很簡單,只要用 pip
指令安裝即可(不過要先用 easy_install
安裝 pip
)。
$ easy_install pip
$ pip install SQLAlchemy
操作 SQLite 資料庫
SQLite 是一個極輕量級的 RDBMS(Relational DataBase Management System),非常適合較小型的非網頁架構應用程式使用,因為它不具備網路的 client/server 架構,所以無法透過網路遠端存取 SQLite 資料庫。
此外,SQLite 對於龐大的查詢、更新等負載能力也不如其他資料庫(MySQL, PostgreSQL 等)出色。即使如此,它仍具備一些十分有用的特性,例如可完全在記憶體中執行的資料庫、很多手持裝置開發環境(iOS, Android)都有支援等等,依然是一個撰寫輕量級應用程式的好選擇!
接下來,可以用範例 1 試著在記憶體中建立 SQLite 資料庫,並且新增一個 user
的表格。
範例1,連接資料庫 Engine 、新增資料表格
1 |
# -*- coding: utf-8 -*- |
執行成功的話,應該會看到類似以下的執行訊息:
1 |
2013-08-21 13:51:39,073 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("user") |
範例 1 說明
先從 35 行的 create_engine('sqlite:///:memory:', echo=True)
談起。
在 SQLAlchemy 的實做過程中,使用了Python 標準的 logging 模組進行開發,因此想要察看 SQLAlchemy 的執行過程的訊息就可以加上參數 echo=True
,就可以看到 SQL 的指令與相關訊息。而 engine
是 SQLAlchemy 的 Engine
實例(instance), Engine
則是可以視為用來介接主要的資料庫(MySQL, SQLite, …)的介面。
值得注意的是,建立 Engine
實例時,實際是還沒真正連接到資料庫的,只有在第一個工作或 SQL 指令被下達,它才會真正連接到資料庫執行。
接著第 38 行,則是使用 Base.metadata.create_all(engine)
在資料庫內建立起相對應的 users
表格。這個用來建立相對應表格以及建立與 Python 類別間的動作,是由 metadata
負責的。
第 40, 41 行則是建立一個 User 類別的實例,並且列印出其所對應的 Python 類別與資料庫表格名稱,其結果為 Mapper|User|user
代表 User
類別映對到 user
資料表。此外,需要注意的是截至目前為止這筆資料仍尚未寫進資料庫內,我們會在後續的範例中學會如何將實例內的資料寫進資料庫中。
再來談談第 9 行的 declarative_base()
,SQLAlchemy 使用了稱為 Declarative system
的類別,用來映對 Python 類別與資料庫表格之間的關聯,所以才會看到第 11 行 User
類別繼承了 Base
,而且又需要在 User
類別中定義 __tablename__
屬性的值,代表它映對到資料庫中的 users
資料表。如果把 Declarative system
想像成 Python 類別介接資料庫的接線生就會相對較好理解,也因此 User
類別需要繼承 Base
才能夠讓 Declarative system
了解表格的欄位名稱、型態、長度以及相對應的 Python 類別。
通常一個應用程式也只會用到一個 declarative_base()
類別(也就是範例 1 的 Base
)。
當然,SQLAlchemy 沒有這麼聰明,可以自動幫我們分別表格欄位的型態、長度、主鍵等,這些都還需要我們自行設計,這些動作也就是第 14 行到第 17 行的內容。第 14 行到第 17 行定義表格的內容,被稱為 Table metadata
,而 User
類別則稱為 Mapped class
,若想知道一個實例映對的資料表名稱與 Python 類別名稱,則可以試著存取 __mapper__
屬性,例如第 41 行。
p.s. 第 14 行到第 17 行的資料表格欄位沒有指定長度,這在 SQLite, PostgreSQL 中是合法的,被稱為 minimal table descriptiopn
,而有指定長度的情況就是 full table description
第 19 行的 __init__
與第 24 行的 __repr__
兩個 Python 預設類別方法。在 SQLAlchemy 這兩個方法是可以省略不寫的。如果沒有覆寫(override) __init__
的話,SQLAlchemy 自行預設的 __init__
就會把所有欄位列為 __init__
的參數,因此若不改寫 __init__
的話,預設的參數就是 id, name, username, password 4 個,而不是第 19 行所定義的 3 個(name, username, password)。
而且在建立一個資料類別的實例時,我們有時會希望對某些表格欄位的值進行檢查或是改寫,例如第 22 行的密碼加密,此時就是需要覆寫 __init__
的情況。最後,覆寫 __repr__
只是為了方便偵錯(debug),讓我們能夠較直觀地觀察User
實例到底存放甚麼數值。
談到此處,就能夠稍微理解使用 ORM 過程就是定義資料庫表格、撰寫資料庫表格對應的 Python 類別、設定資料庫表格與其他資料庫表格間的關聯等動作。
截至目前為止,範例 1 仍未真正與資料庫進行互動,僅止於建立資料庫 Engine 、定義資料基模(scheme)。
事實上,如果要真正與資料庫進行互動(新增、刪除、修改)就得建立 Session
進行。
範例 2 將說明如何建立 Session 與資料庫進行互動。
範例 2 ,建立 Session 與資料庫互動
1 |
# -*- coding: utf-8 -*- |
如果執行成功的話,會出現類似以下的結果:
1 |
2013-08-21 17:57:32,546 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("user") |
範例 2 說明
定義類別的部份在範例 1 中已經做了不少說明,在範例 2 中就不多做說明了。
直接從第 37 行的部份開始說明,第 37 行 sessionmaker(bind=engine)
將 engine
綁定(bind)到 Session
類別中,接著我們就能在第 38 行中將這個已經與 engine
綁定的 Session
類別實例化,以開始進行與資料庫的互動。
此外, Session 類別用以下的方法進行綁定。等於是先建立一個未綁定的 Session ,稍後再將 Engine 綁定。
1 |
Session = sessionmaker() |
有了 session 實例之後,我們將 1 筆 user_1
資料交給 session
準備 加入到資料庫之中,也就是第 41 行的部份。
為甚麼是 準備 呢?因為此時的資料庫還未沒有 user_1
的資料,此時的狀態被稱為 pending
(事實上,共有 4 種狀態 Transient, Pending, Persistent, Detached)。
那甚麼時候這些資料才會被新增到資料庫內呢?只有進行 QUERY, COMMIT, FLUSH 時才會被寫入資料庫內。
因此當第 42 行進行 user1 的查詢時,SQLAlchemy 會先將 user_1
的資料寫入資料庫中,再進行查詢。所以其執行結果先出現了 INSERT,接著才出現 SELECT 。
接著,第 43 行至第 47 行的部份則是用來判斷是否能夠查詢到 user_1
的資料, filter_by(name="user_1")
是對欄位名稱為 name 所下的查詢條件,first()
則是回傳查詢結果的第1筆。
事實上,使用 query()
方法時,若有查詢到結果會回傳 Query Object,若無則是回傳 None 。
然後第 49 行的部份,我們利用 session 的 rollback()
方法,將資料庫狀態回到尚未加入 user_1
時的狀態。
第 51 行到第 56 行則是再查詢一次 user_1
的資料,想當然,這筆資料將無法查詢得到,因為資料庫狀態已經回到尚未加入 user_1
時的狀態了。
最後,第 59 行則是再將 user_2
的資料加到 session 內。然後直接在第 60 行使用 session 的 commit()
方法,告訴 session 要直接將這筆資料寫入資料庫內,所以就不需等到要查詢時才會寫入到資料庫內。
到此,大家應已能夠掌握 Session 的基本操作了。
如果有需要了解更多關於 Session 的操作可以至 SQLAlchemy 中的 Session 篇察看。
參考資料:
Python SQLAlchemy --1的更多相关文章
- python SQLAlchemy
这里我们记录几个python SQLAlchemy的使用例子: 如何对一个字段进行自增操作 user = session.query(User).with_lockmode('update').get ...
- Python SQLAlchemy --3
本文為 Python SQLAlchemy ORM 一系列教學文: 刪除 學會如何查詢之後,就能夠進行後續的刪除.更新等操作. 同樣地,以幾個範例做為學習的捷徑. 123456789 user_1 = ...
- Python SQLAlchemy --2
本文為 Python SQLAlchemy ORM 一系列教學文: 接下來會更深入地探討查詢的使用. 查詢的基本使用法為 session.query(Mapped Class),其後可加 .group ...
- Python SqlAlchemy使用方法
1.初始化连接 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker engine = create ...
- python+SQLAlchemy+爬虫
python+SQLAlchemy+爬虫 前面分享了SQLAlchemy的知识,这次我共享一下学习用python开发爬虫再把爬出来的数据放到用SQLAlchemy的数据库上面的知识,当然我这个是带测试 ...
- Python.SQLAlchemy.0
1. SQLAlchemy and You http://lucumr.pocoo.org/2011/7/19/sqlachemy-and-you/ 2. Overview http://docs.s ...
- Python SQLAlchemy基本操作和常用技巧包含大量实例,非常好python
http://www.makaidong.com/%E8%84%9A%E6%9C%AC%E4%B9%8B%E5%AE%B6/28053.shtml "Python SQLAlchemy基本操 ...
- Python SQLAlchemy入门教程
本文将以Mysql举例,介绍sqlalchemy的基本用法.其中,Python版本为2.7,sqlalchemy版本为1.1.6. 一. 介绍 SQLAlchemy是Python中最有名的ORM工具. ...
- Python—sqlalchemy
SQLAlchemy SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作. #Dialect用于和数据API进行交流,根据配置文 ...
随机推荐
- 《JS高程》中的正则的复杂模式的总结
复杂模式: *分组: var reDogDog=/dogdog/g;---------------var reDogDog=/(dog){2}/g; *引用:(注意带括号和不带括号) var sMat ...
- .NET程序集的编译目标平台:X86 &AnyCPU &X64
在我们测试平台上发布客户端组件,经常会碰到因为build的版本是x86还是anycpu而引起的application error的问题.借此,研究了一下X86,X64,AnyCPU的区别. 使用.ne ...
- cmd执行mysql操作
(以下已安装到本机的mysql为例) 登录mysql数据库,如果没有在环境变量配置path到mysql中的bin目录,需要手动进入该目录中 执行:mysql -u用户名 -p密码 (注意:只要进入了m ...
- Spring对 JDBC 的支持,JdbcTemplate类的使用
导包:spring框架的包 和 连接数据库连接池的c3p0包 连接mysql数据库的包; 在src目录下建立jdbc.properties文件:存放连接数据库的属性值 jdbc.user=root j ...
- gulp使用笔记
gulp简介 gulp 是基于 Nodejs 的自动任务运行器,能自动化地完成javascript/coffee/sass/less/html/image/css等文件的的测试.检查.合并.压缩.格式 ...
- 在MFC中使用GDI+的一般方法,以VC6.0编译器为例
1.载解压GDI+开发包: 2.正确设置include & lib 目录: 设置如下:VC6.0编译器菜单Tools->Options->Directories中添加inlude ...
- Linux:安装rstatd,报错
[安装] 下载地址:http://heanet.dl.sourceforge.net/sourceforge/rstatd/安装:一次执行--tar -xzvf rpc.rstatd-4.0.1.ta ...
- delphi Style TBitmapLink
New Bitmap Links Editor http://docwiki.appmethod.com/appmethod/1.17/topics/en/What's_New A new edito ...
- CSS3知识点总结----属性选择器
1.E[attr]只使用属性名,但没有确定任何属性值 2.E[attr="value"]指定属性名,并指定了该属性的属性值 3.E[attr~="value"] ...
- bootstrap dialog 使用模态对话框
bootstrap3-dialog 使用模态对话框 <div class="modal fade"> <div class="modal-dialog& ...