欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
使用 SQLAlchemy

Noah Gift, 軟件工程師, Giftcs

2008 年 10 月 23 日

SQLAlchemy 是下一代的 Python Object Relational 映射器。通過(guò)本文您將了解如何使用新的 0.5 API、與第三方組件協(xié)作,并構建一個(gè)基本的 Web 應用程序。

簡(jiǎn)介

對 象關(guān)系映射器(Object Relational Mappers,ORM)在過(guò)去數年吸引了不少人的目光。主要原因是 ORM 經(jīng)常會(huì )在 Web 應用程序框架中被提起,因為它是快速開(kāi)發(fā)(Rapid Development)棧中的關(guān)鍵組件。Django 和 Ruby on Rails 等 Web 框架采用了設計一個(gè)獨立棧的方法,將自主開(kāi)發(fā)的 ORM 緊密集成到該框架中。而其他框架,如 Pylons、Turbogears 和 Grok,則采用更加基于組件的架構結合可交換的第三方組件。兩種方法都有各自的優(yōu)勢:緊密集成允許非常連貫的體驗(如果問(wèn)題映射到框架),而基于組件的 架構則允許最大的設計靈活性。但是,本文的主題并不是 Web 框架;而是 SQLAlchemy。

SQLAlchemy 在構建在 WSGI 規范上的下一代 Python Web 框架中得到了廣泛應用,它是由 Mike Bayer 和他的核心開(kāi)發(fā)人員團隊開(kāi)發(fā)的一個(gè)單獨的項目。使用 ORM 等獨立 SQLAlchemy 的一個(gè)優(yōu)勢就是它允許開(kāi)發(fā)人員首先考慮數據模型,并能決定稍后可視化數據的方式(采用命令行工具、Web 框架還是 GUI 框架)。這與先決定使用 Web 框架或 GUI 框架,然后再決定如何在框架允許的范圍內使用數據模型的開(kāi)發(fā)方法極為不同。

什么是 WSGI?

WSGI 是下一代 Python Web 框架、應用程序和服務(wù)器應該遵循的規范。WSGI 中 一個(gè)有趣的方面是創(chuàng )建 Python 中間件,并在使用 Python 或任何語(yǔ)言創(chuàng )建的 Web 應用程序中使用。請參閱 參考資料,獲取關(guān)于 WSGI 和 WSGI 社區(Pypefitters)的大量鏈接。

SQLAlchemy 的一個(gè)目標是提供能兼容眾多數據庫(如 SQLite、MySQL、Postgres、Oracle、MS-SQL、SQLServer 和 Firebird)的企業(yè)級持久性模型。SQLAlchemy 正處于積極開(kāi)發(fā)階段,當前最新的 API 將圍繞版本 0.5 設計。請參閱參考資料部分,獲取官方 API 文檔、教程和 SQLAlchemy 書(shū)籍的鏈接。

SQLAlchemy 取得成功的一個(gè)證明就是圍繞它已建立了豐富的社區。針對 SQLAlchemy 的擴展和插件包括:declarative、Migrate、Elixir、SQLSoup、django-sqlalchemy、 DBSprockets、FormAlchemy 和 z3c.sqlalchemy。在本文中,我們將學(xué)習一篇關(guān)于新 0.5 API 的教程,探究一些第三方庫,以及如何在 Pylons 中使用它們。

誰(shuí)是 Mike Bayer?

Michael Bayer 是居住在紐約的一名軟件承包商,他擁有十余年處理各類(lèi)關(guān)系數據庫的經(jīng)驗。他曾使用 C、Java? 和 Perl 編寫(xiě)了許多自主研發(fā)的數據庫抽象層,并在 Major League Baseball 與大量多服務(wù)器 Oracle 系統打了多年交道,借助這些經(jīng)驗,他成功編寫(xiě)了 “終極工具包” SQLAlchemy,用于生成 SQL 和處理數據庫。其目標是貢獻一個(gè)世界級、獨樹(shù)一幟的面向 Python 的工具包,以幫助 Python 成為一個(gè)廣泛普及的編程平臺。

安裝

本文假定您使用 Python 2.5 或更高版本,并且安裝了子版本。Python 2.5 包括 SQLite 數據庫,因此也是測試 SQLALchemy 內存的好工具。如果您已經(jīng)安裝了 Python 2.5,則只需通過(guò)設置工具安裝 sqlalchemy 0.5 beta 。要獲取設置工具腳本,請在您的終端中下載并運行以下 4 條命令:

  wget http://peak.telecommunity.com/dist/ez_setup.py                    python ez_setup.py                    sudo easy_install http://svn.sqlalchemy.org/sqlalchemy/trunk                    sudo easy_install ipython                    

前 三行代碼檢查最新版本的 sqlalchemy,并將它作為包添加到您本地系統的 Python 安裝中。最后一個(gè)代碼片段將安裝 IPython,它是一個(gè)實(shí)用的聲明式 Python 解釋器,我將在本文中使用它。首先,我需要測試已安裝的 SQLAlchemy 版本。您可以測試自己的版本是否為 0.5.x,方法是在 IPython 或普通 Python 解釋器中發(fā)起以下命令。

 In [1]: import sqlalchemy                    In [2]: sqlalchemy.__version__                    Out[2]: '0.5.0beta1'                    

SQLAlchemy 0.5 快速入門(mén)指南

新的 0.5 發(fā)行版在 SQLAlchemy 中引入了一些顯著(zhù)的變更。此外列出了這些變更的概要信息:

  • 聲明式擴展是多數情況下建議的開(kāi)始方式。
  • session.query() 可以接受任意組合的 class/column 表達式。
  • session.query() 或多或少也是 select() 的支持 ORM 的替代方法。
  • 查詢(xún)提供了一些試驗性的 update()/delete() 方法,用于實(shí)現基于標準的更新/刪除。
  • 會(huì )話(huà)將在 rollback() 和 commit() 方法后自動(dòng)過(guò)期;因此使用默認的 sessionmaker() 意味著(zhù)您通常不必調用 clear() 或 close();對象將自動(dòng)與當前的事務(wù)同步。
  • 使用 session.add()、session.add_all()(save/update/save_or_update 已刪除)在會(huì )話(huà)中添加內容。

雖然 declarative 擴展從 0.4 開(kāi)始便一直出現在 SQLAlchemy 中,但它也經(jīng)過(guò)了一些小修改,這使它在大多數 SQLAlchemy 項目中都成為了一種強有力的便捷方式。新的 declarative 語(yǔ)法允許在一步中創(chuàng )建表、類(lèi)和數據庫映射。下面我們來(lái)看看這種新語(yǔ)法的工作原理,以我編寫(xiě)的一個(gè)用于跟蹤文件系統變化的工具為例。


清單 1. 新 SQLAlchemy 聲明樣式
                    #/usr/bin/env python2.5                    #Noah Gift                    from sqlalchemy.ext.declarative import declarative_base                    from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey                    Base = declarative_base()                    class Filesystem(Base):                    __tablename__ = 'filesystem'                    path = Column(String, primary_key=True)                    name = Column(String)                    def __init__(self, path,name):                    self.path = path                    self.name = name                    def __repr__(self):                    return "<Metadata('%s','%s')>" % (self.path,self.name)                    

通 過(guò)這種新的聲明樣式,SQLAlchemy 能夠在一步中創(chuàng )建一個(gè)數據庫表、創(chuàng )建一個(gè)類(lèi)以及類(lèi)與表之間的映射。如果您剛開(kāi)始接觸 SQLAlchemy,或許應該學(xué)習這種建立 ORM 的方法。此外,了解另一種更加顯式地控制各步驟的方式也是有益的(如果您的項目要求這種級別的詳細程度)。

在閱讀這段代碼時(shí),需要指出一些可能會(huì )讓初次接觸 SQLAlchemy 或聲明性擴展的用戶(hù)犯難的地方。首先,

Base = declarative_base()

行創(chuàng )建了一個(gè)類(lèi),稍后的 Filesystem 類(lèi)便繼承自該類(lèi)。如果您保存并在 declarative_style 中運行該代碼,然后將它導入到 IPython 中,則會(huì )看到以下輸出:
In [2]: declarative_style.Filesystem?                    Type:		DeclarativeMeta                    Base Class:	<class 'sqlalchemy.ext.declarative.DeclarativeMeta'>                    String Form:	<class 'declarative_style.Filesystem'>                    

這個(gè) DeclarativeMeta 類(lèi)型的魔力就是允許所有操作發(fā)生在一個(gè)簡(jiǎn)單的類(lèi)定義中。

另一個(gè)需要指出的地方是本示例并未實(shí)際執行任何操作。在運行創(chuàng )建表的代碼之前,將不會(huì )創(chuàng )建實(shí)際的表,并且,您還需要定義 SQLAlchemy 將使用的數據庫引擎。這兩行代碼如下所示:

       engine = create_engine('sqlite:///meta.db', echo=True)                    Base.metadata.create_all(engine)                    

SQlite 是試驗 SQLAlchemy 的理想選擇,并且您還可以選擇使用內存數據庫,在這種情況下,您的代碼行應如下所示:

        engine = create_engine('sqlite:///:memory:', echo=True)                    

或者,只創(chuàng )建一個(gè)簡(jiǎn)單的文件,如第一個(gè)例子所示。如果您選擇創(chuàng )建一個(gè)基于 SQLite 文件的數據庫,則可以通過(guò)拋棄數據庫中的所有表從零開(kāi)始,而不需要刪除文件。為此,您可以發(fā)起以下代碼行:

                    Base.metadata.drop_all(engine)                    

此 時(shí),我們已經(jīng)了解了創(chuàng )建 SQLAlchemy 項目和通過(guò) SQLAlchemy API 控制數據庫所需的知識。在開(kāi)始實(shí)際應用之前,惟一需要掌握一點(diǎn)是會(huì )話(huà)的概念。SQLAlchemy “官方” 文檔將會(huì )話(huà)描述為數據庫的句柄。在實(shí)際應用中,它允許不同的基于事務(wù)的連接發(fā)生在 SQLAlchemy 一直在等待的連接池中。在會(huì )話(huà)內部,這通常是添加數據到數據庫中、執行查詢(xún)或刪除數據。

要創(chuàng )建會(huì )話(huà),請執行下面這些后續步驟:

        #establish Session type, only need to be done once for all sessions                    Session = sessionmaker(bind=engine)                    #create record object                    create_record = Filesystem("/tmp/foo.txt", "foo.txt")                    #make a unique session                    session = Session()                    #do stuff in session.  We are adding a record here                    session.add(create_record)                    #commit the transaction                    session.commit()                    

這 些就是使 SQLAlchemy 正常運行所需的所有工作。雖然 SQLAlchemy 提供了一個(gè)非常復雜的 API 來(lái)處理許多復雜的事情,但它實(shí)際上非常容易使用。在本節結束時(shí),我還想指出,上例使用 echo=True 創(chuàng )建引擎。這是查看由 SQLAlchemy 創(chuàng )建的 SQL 的便捷方法。對于 SQLAlchemy 初學(xué)者,強烈建議使用該方法,因為它會(huì )讓您覺(jué)得 SQLAlchemy 不再那么神秘?,F在,運行自己創(chuàng )建的一些代碼,并查看 SQL 創(chuàng )建表的過(guò)程。


清單 2. SQLAlchemy SQL 表創(chuàng )建輸出
2008-06-22 05:33:46,403 INFO                    sqlalchemy.engine.base.Engine.0x..ec PRAGMA                    table_info("filesystem")                    2008-06-22 05:33:46,404 INFO sqlalchemy.engine.base.Engine.0x..ec {}                    2008-06-22 05:33:46,405 INFO sqlalchemy.engine.base.Engine.0x..ec                    CREATE TABLE filesystem (                    path VARCHAR NOT NULL,                    name VARCHAR,                    PRIMARY KEY (path)                    )                    

Pylesystem:類(lèi)似于 Spotlight 或 Beagle 的實(shí)時(shí)文件系統元數據索引程序

抽 象地討論如何使用某個(gè)工具會(huì )讓許多人不好理解,因此,我將使用 SQLAlchemy 演示如何創(chuàng )建一個(gè)元數據工具。此工具的目標是監控文件系統、創(chuàng )建和刪除事件,以及在一個(gè) SQLAlchemy 數據庫中保存這些變更的記錄。如果您曾經(jīng)在 OS X 上使用過(guò) Spotlight,或在 Linux? 上使用過(guò) Beagle,那就應該使用過(guò)一款實(shí)時(shí)的文件系統索引工具。要繼續本文,您需要運行 Linux 內核 2.6.13 或更高版本。

下一個(gè)示例比較大,大約有 100 行代碼。查看整個(gè)示例并運行它,然后,我將介紹代碼各部分的作用。要運行此腳本,您必須在終端中執行以下步驟:

  1. wget http://peak.telecommunity.com/dist/ez_setup.py
  2. sudo python ez_setup.py
  3. sudo easy_install
    "http://git.dbzteam.org/?p=pyinotify.git;a=snapshot;h=HEAD;sf=tgz"
  4. sudo easy_install http://svn.sqlalchemy.org/sqlalchemy/trunk

清單 3. 文件系統事件監控數據庫
#/usr/bin/env python2.5                    #Noah Gift 06/21/08                    #tweaks by Mike Bayer 06/22/08                    import os                    from sqlalchemy.ext.declarative import declarative_base                    from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey                    from sqlalchemy import create_engine                    from sqlalchemy.orm import sessionmaker                    from sqlalchemy.orm import scoped_session                    from pyinotify import *                    path = "/tmp"                    #SQLAlchemy                    engine = create_engine('sqlite:///meta.db', echo=True)                    Base = declarative_base()                    Session = scoped_session(sessionmaker(bind=engine))                    class Filesystem(Base):                    __tablename__ = 'filesystem'                    path = Column(String, primary_key=True)                    name = Column(String)                    def __init__(self, path,name):                    self.path = path                    self.name = name                    def __repr__(self):                    return "<Metadata('%s','%s')>" % (self.path,self.name)                    def transactional(fn):                    """add transactional semantics to a method."""                    def transact(self, *args):                    session = Session()                    try:                    fn(self, session, *args)                    session.commit()                    except:                    session.rollback()                    raise                    transact.__name__ = fn.__name__                    return transact                    class ProcessDir(ProcessEvent):                    """Performs Actions based on mask values"""                    @transactional                    def process_IN_CREATE(self, session, event):                    print "Creating File and File Record:", event.pathname                    create_record = Filesystem(event.pathname, event.path)                    session.add(create_record)                    @transactional                    def process_IN_DELETE(self, session, event):                    print "Removing:", event.pathname                    delete_record = session.query(Filesystem).                    filter_by(path=event.pathname).one()                    session.delete(delete_record)                    def init_repository():                    #Drop the table, then create again with each run                    Base.metadata.drop_all(engine)                    Base.metadata.create_all(engine)                    session = Session()                    #Initial Directory Walking Addition Brute Force                    for dirpath, dirnames, filenames in os.walk(path):                    for file in filenames:                    fullpath = os.path.join(dirpath, file)                    record = Filesystem(fullpath, file)                    session.add(record)                    session.flush()                    for record in session.query(Filesystem):                    print "Database Record Number: Path: %s , File: %s "                     % (record.path, record.name)                    session.commit()                    if __name__ ==  "__main__":                    init_repository()                    #Pyionotify                    wm = WatchManager()                    mask = IN_DELETE | IN_CREATE                    notifier = ThreadedNotifier(wm, ProcessDir())                    notifier.start()                    wdd = wm.add_watch(path, mask, rec=True)                    

要查看此腳本的實(shí)際運行結果,您需要打開(kāi)兩個(gè)終端窗口。在第一個(gè)窗口中,運行 pylesystem.py 腳本。您將看到一系列輸出內容,如下所示(請注意,以下版本經(jīng)過(guò)適當縮減):

2008-06-22 07:18:08,707 INFO                    sqlalchemy.engine.base.Engine.0x..ec ['/tmp/ba.txt', 'ba.txt']                    2008-06-22 07:18:08,710 INFO                    sqlalchemy.engine.base.Engine.0x..ec COMMIT                    2008-06-22 07:18:08,715 INFO                    sqlalchemy.engine.base.Engine.0x..ec BEGIN                    2008-06-22 07:18:08,716 INFO                    sqlalchemy.engine.base.Engine.0x..ec SELECT filesystem.path                    AS filesystem_path, filesystem.name AS filesystem_name                    FROM filesystem                    2008-06-22 07:18:08,716 INFO sqlalchemy.engine.base.Engine.0x..ec []                    Database Record Number: Path: /tmp/ba.txt , File: ba.txt                    

第一個(gè)腳本運行一個(gè)多線(xiàn)程文件系統事件監控引擎,它將 /tmp 的所有創(chuàng )建和刪除變更寫(xiě)入到 sqlalchemy 數據庫中。注意:由于它是多線(xiàn)程的,當您 完成此教程時(shí),需要鍵入 Control + \ 來(lái)停止線(xiàn)程應用程序。

成功運行之后,您可以在第二個(gè)終端窗口中創(chuàng )建事件,新創(chuàng )建或刪除的文件將實(shí)時(shí)添加到數據庫中或從數據庫中刪除。如果您只創(chuàng )建了 /tmp 目錄中的某個(gè)文件,比如說(shuō) touch foobar.txt,則會(huì )在第一個(gè)窗口中看到以下輸出:

Creating File and File Record: /tmp/foobar.txt                    2008-06-22 08:02:19,468 INFO                    sqlalchemy.engine.base.Engine.0x..4c BEGIN                    2008-06-22 08:02:19,471 INFO                    sqlalchemy.engine.base.Engine.0x..4c INSERT INTO filesystem (path, name) VALUES (?, ?)                    2008-06-22 08:02:19,472 INFO                    sqlalchemy.engine.base.Engine.0x..4c ['/tmp/foobar.txt', '/tmp']                    2008-06-22 08:02:19,473 INFO                    sqlalchemy.engine.base.Engine.0x..4c COMMIT                    

記得您之前啟用了 SQL echo 嗎?鑒于此,當代碼將此新條目添加到文件系統中時(shí),您可以看到 SQL 語(yǔ)句。如果您現在刪除該文件,您也可以看到刪除的過(guò)程。下面是您鍵入 rm 語(yǔ)句 rm foobar.txt 時(shí)的輸出:

Removing: /tmp/foobar.txt                    2008-06-22 08:06:01,727 INFO                    sqlalchemy.engine.base.Engine.0x..4c BEGIN                    2008-06-22 08:06:01,733 INFO                    sqlalchemy.engine.base.Engine.0x..4c SELECT filesystem.path                    AS filesystem_path, filesystem.name AS filesystem_name                    FROM filesystem                    WHERE filesystem.path = ?                    LIMIT 2 OFFSET 0                    2008-06-22 08:06:01,733 INFO                    sqlalchemy.engine.base.Engine.0x..4c ['/tmp/foobar.txt']                    2008-06-22 08:06:01,736 INFO                    sqlalchemy.engine.base.Engine.0x..4c DELETE FROM filesystem WHERE filesystem.path = ?                    2008-06-22 08:06:01,736 INFO                    sqlalchemy.engine.base.Engine.0x..4c [u'/tmp/foobar.txt']                    2008-06-22 08:06:01,737 INFO                    sqlalchemy.engine.base.Engine.0x..4c COMMIT                    

在 Filesystem 類(lèi)中,您添加了一個(gè) transactional 方法,您將使用一個(gè)修飾類(lèi)來(lái)處理將文件系統事件提交給數據庫的語(yǔ)義。Pyinotify 中的實(shí)際 Filesystem I/O 監控由 ProcessDir 類(lèi)完成,該類(lèi)繼承自 ProcessEvents 并覆蓋了其中的方法。如果您注意了 process_IN_CREATE 和 process_IN_DELETE 方法,會(huì )發(fā)現它們都附加了一個(gè) transactional 修飾類(lèi)。隨后,它們將接受創(chuàng )建或刪除事件并對數據庫執行修改。

還有一個(gè)名稱(chēng)為 initial_repository 的方法,每次運行腳本時(shí)它都會(huì )填充數據庫,實(shí)現方法是銷(xiāo)毀數據庫中的表并重新創(chuàng )建。腳本的最底部將通知 Pyinotify 代碼以不確定的方式運行,而這最終表示作為守護進(jìn)程運行。

結束語(yǔ)

本文介紹了 SQLAlchemy 的一些特性,并演示了它和 API 的使用是多么簡(jiǎn)單。借助 SQLAlchemy 和開(kāi)源庫 Pyinotify,您還使用不到 100 行 Python 代碼構建了一個(gè) 功能異常強大的工具。這是簡(jiǎn)單但功能強大的 ORM 的特性之一。它消除了復雜的關(guān)系數據庫處理操作,現在它為用戶(hù)添加了快樂(lè )而不是負擔。隨后,這些省下來(lái)的精力可以用于解決感興趣的問(wèn)題,因為 SQLAlchemy 將是最簡(jiǎn)單的環(huán)節。

如果您有興趣了解更多關(guān)于 SQLAlchemy 的信息,則應該閱讀本文末尾列出的 參考資料。 其中包括一本出色的書(shū)籍和大量?jì)?yōu)秀的在線(xiàn)文檔,您可以考慮研究其他一些使用 SQLAlchemy 的項目并擴展它們。最近一個(gè)較有興趣的 SQLAlchemy 相關(guān)項目就是 Website reddit.com。它使用純 WSGI 框架 Pylons 構建,并整合了 SQLAlchemy 作為其默認 ORM。我附帶了到 reddit 完整源代碼的鏈接。借助新掌握的 SQLAlchemy 知識,您應該能夠快速實(shí)現自己的 reddit,并且應該能執行一些數據庫查詢(xún)操作。祝您好運!

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
通過(guò)demo學(xué)習OpenStack開(kāi)發(fā)——數據庫(1)
一個(gè)超方便使用SQL的Python神器
python實(shí)用技術(shù)之ORM
第 86 天:Python SQLAlchemy
小技巧 | 聊聊 Python 中數據庫反向生成 Model 最優(yōu)方案
Python操作MySql——使用SQLAlchemy ORM操作數據庫
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久