指南:從模型定義到復合查詢的完整入門)
peewee ORM 實戰(zhàn)指南從模型定義到復合查詢的完整入門【免費下載鏈接】peeweea small, expressive orm -- supports postgresql, mysql, sqlite, now with asyncio項目地址: https://gitcode.com/gh_mirrors/pe/peeweePeewee 是一個簡單而小巧的 Python ORM對象關系映射庫核心代碼集中在一個文件 peewee.py 中概念少而表達力強容易學習且使用直觀。本文以倉庫根目錄 README.rst 為骨架結合項目源碼、文檔與示例應用帶你從零掌握 Peewee 的模型定義、數據寫入、查詢組合、關聯 JOIN、聚合分頁與原子更新并了解其擴展生態(tài)與實戰(zhàn)案例。Peewee 是什么按照 README 的定位Peewee 是 a small, expressive ORM核心特性包括概念極少、表達力強易于學習且使用直覺化支持 Python 2.7 與 3.4當前倉庫 peewee.py 中版本號為3.17.8原生支持SQLite、MySQL、MariaDB、PostgreSQL四類數據庫擁有數量龐大的擴展庫Playhouse覆蓋全文檢索、連接池、遷移、逆向工程等能力。Peewee 的模型風格與 Django 相似模型類對應數據庫表、字段實例對應表的列、模型實例對應表中的行三者映射關系清晰直接。同時Peewee 提供了聲明式模型定義、鏈式查詢構建器、SQL 函數fn支持以及 Django 風格的Meta配置類。說明README 中提到的 Python 2.7 為歷史兼容范圍。當前倉庫源碼基于現代 Python 特性開發(fā)并提供了基于 Cython 的可選 C 擴展加速見 setup.py建議在較新的 Python 3 環(huán)境中使用。安裝與依賴Peewee 通過標準setup.py發(fā)布。安裝時可選編譯 C 擴展playhouse._sqlite_udf、playhouse._sqlite_ext如果安裝了 Cython 會從.pyx生成擴展模塊否則回退到預生成的 C 文件前提是運行在 CPython 上見 setup.py。數據庫驅動方面peewee.py 會按優(yōu)先級自動探測可用驅動SQLite 優(yōu)先使用pysqlite3/pysqlite2否則回退標準庫sqlite3PostgreSQL 支持psycopg2含psycopg2cffi兼容層與新版psycopg3MySQL 優(yōu)先PyMySQL回退MySQLdb。因此你只需為所用數據庫安裝對應驅動即可無需額外配置。學習路線圖README 為新用戶規(guī)劃了一條循序漸進的學習路徑對應的倉庫文檔如下主題倉庫文檔快速上手docs/peewee/quickstart.rst完整示例Twitter 風格 Web 應用docs/peewee/example.rst、examples/twitter/app.py交互式使用docs/peewee/interactive.rst模型與字段docs/peewee/models.rst查詢docs/peewee/querying.rst關系與連接docs/peewee/relationships.rst數據庫配置docs/peewee/database.rst查詢操作符docs/peewee/query_operators.rstREADME 強烈建議打開一個交互式 Python Shell 邊敲邊學這樣能直觀感受查詢表達式的構建過程。定義模型以 README 中的 User/Tweet 模型為例定義模型與 Django、SQLAlchemy 類似from peewee import * import datetime db SqliteDatabase(my_database.db) class BaseModel(Model): class Meta: database db class User(BaseModel): username CharField(uniqueTrue) class Tweet(BaseModel): user ForeignKeyField(User, backreftweets) message TextField() created_date DateTimeField(defaultdatetime.datetime.now) is_published BooleanField(defaultTrue)關鍵點解讀數據庫實例SqliteDatabase(my_database.db)管理 SQLite 連接也可以替換為MySQLDatabase、MariaDBDatabase、PostgresqlDatabase等分別對應 peewee.py 中的MySQLDatabase、PostgresqlDatabase類。BaseModel 約定把database放在基類的Meta中后續(xù)所有模型繼承它即可復用數據庫配置避免重復聲明這是官方推薦做法見 docs/peewee/models.rst。字段與默認值created_date、is_published都帶default寫入時未顯式賦值會自動使用默認值。外鍵與反向引用ForeignKeyField(User, backreftweets)讓User實例可以通過user.tweets訪問其所有推文。主鍵未顯式指定primary_key時Peewee 會自動添加名為id的自增整數主鍵AutoField。連接數據庫并建表db.connect() db.create_tables([User, Tweet])db.connect()顯式打開連接是良好實踐能立刻暴露數據庫連接錯誤而不是等到第一條查詢執(zhí)行時才報錯。create_tables()會為模型創(chuàng)建包含正確列、索引、序列sequence和外鍵約束的表。寫入數據create 與 savecharlie User.create(usernamecharlie) huey User(usernamehuey) huey.save() # created_date / is_published 未賦值將使用字段默認值 Tweet.create(usercharlie, messageMy first tweet)User.create(...)直接插入一行并返回模型實例User(usernamehuey)先構造實例再調用save()持久化save()返回受影響行數Tweet.create(usercharlie, ...)中外鍵可以直接傳模型實例也可傳對應主鍵值見 docs/peewee/querying.rst字段默認值defaultdatetime.datetime.now、defaultTrue在插入時自動生效。底層上Model.create會構建一個InsertQuery并執(zhí)行同時自動回填主鍵到實例參見 peewee.py 中Model.create與InsertQuery的實現。查詢從單條到復合條件單條記錄User.get(User.username charlie)Model.get是User.select().where(...).get()的簡寫形式返回滿足條件的單條記錄無匹配時拋出DoesNotExist。列表查詢與 IN 子查詢usernames [charlie, huey, mickey] users User.select().where(User.username.in_(usernames)) tweets Tweet.select().where(Tweet.user.in_(users))第二條查詢展示了子查詢能力Tweet.user.in_(users)中傳入的是一個查詢對象Peewee 會將其編譯為IN (SELECT ...)形式。查詢構建器支持任意嵌套這正是 Peewee 表達力強的體現。等價的 JOIN 寫法tweets (Tweet .select() .join(User) .where(User.username.in_(usernames)))以上兩種寫法結果等價前者使用子查詢后者使用INNER JOIN。JOIN常量定義在 peewee.pyLEFT_OUTERLEFT OUTER JOIN支持INNER、LEFT_OUTER、RIGHT_OUTER、FULL、CROSS等連接類型。組合條件與日期過濾tweets_today (Tweet .select() .where( (Tweet.created_date datetime.date.today()) (Tweet.is_published True)) .count())、|、~分別對應 SQL 的 AND、OR、NOT多個條件可以任意括號嵌套count()直接生成SELECT COUNT(*)聚合查詢返回整數。排序User.select().order_by(User.username).paginate(3, 20)order_by支持.asc()/.desc()也可.desc(nulls...)控制 NULL 排序paginate(page, paginate_by)按頁取數默認每頁 20 條上述代碼返回第 3 頁第 41–60 條。paginate方法定義于 peewee.py本質是limit(paginate_by).offset((page - 1) * paginate_by)。聚合與分組統計每個用戶的推文數tweet_ct fn.Count(Tweet.id) users (User .select(User, tweet_ct.alias(ct)) .join(Tweet, JOIN.LEFT_OUTER) .group_by(User) .order_by(tweet_ct.desc()))要點fn是 Peewee 提供的 SQL 函數入口定義于 peewee.pyfn Function(None, None)可調用任意 SQL 函數如fn.Count、fn.Lower、fn.Substrtweet_ct.alias(ct)編譯為COUNT(tweet.id) AS ct查詢結果中ct會作為屬性掛到返回的User實例上使用JOIN.LEFT_OUTER保證沒有推文的用戶計數為 0也不會被過濾掉group_by(User)按用戶分組order_by(tweet_ct.desc())按計數倒序排列。類似地fn.Lower(fn.Substr(Person.name, 1, 1)) g這類嵌套函數表達式可直接用于where過濾見 docs/peewee/quickstart.rst 的 SQL Functions 一節(jié)。原子更新避免競態(tài)條件Counter.update(countCounter.count 1).where(Counter.url request.url)README 特別強調對于讀取后再寫入的計數類操作絕不能在兩步中完成存在競態(tài)條件而應使用單條原子 UPDATE 表達式。Counter.count 1會被編譯為 SQL 側的count count 1在數據庫層面原子執(zhí)行天然規(guī)避并發(fā)問題。源碼級印證核心機制一覽能力實現位置說明版本號peewee.py__version__ 3.17.8JOIN 常量peewee.pyLEFT_OUTERLEFT OUTER JOIN等SQL 函數入口peewee.pyfn Function(None, None)分頁peewee.pySelect.paginate(page, paginate_by20)事務/原子操作peewee.pyDatabase.atomic()上下文管理器驅動探測peewee.pySQLite/psycopg2/psycopg3/PyMySQL 自動選擇C 擴展構建setup.pyCython 可選加速atomic()支持嵌套事務與保存點savepoint是批量寫入、保證一致性的常用手段。例如將insert_many包進with db.atomic():可以顯著提升批量插入速度并保證要么全部成功、要么全部回滾。擴展生態(tài)playhousePeewee 的擴展以playhouse命名空間組織詳見 playhouse/README.md覆蓋三大類數據庫廠商擴展SQLite 擴展FTS3/4/5 全文檢索、BM25 排序算法、虛擬表、閉包表、JSON、LSM 鍵值存儲、BLOB 與在線備份 API見 playhouse/sqlite_ext.py、APSW 驅動playhouse/apsw_ext.py、SQLCipher 加密庫playhouse/sqlcipher_ext.py、SqliteQ 專用寫線程playhouse/sqliteq.py、PostgreSQL 擴展JSON/JSONB、HStore、數組、服務端游標、全文檢索見 playhouse/postgres_ext.py與 MySQL 擴展playhouse/mysql_ext.py高層工具庫Compressed/Pickle 字段playhouse/fields.py、模型與字典互轉playhouse/shortcuts.py、Hybrid 屬性playhouse/hybrid.py、信號機制 pre/post-save、delete、initplayhouse/signals.py、類 dataset 的高層 APIplayhouse/dataset.py、鍵值存儲playhouse/kv.py數據庫管理與框架集成pwiz 逆向生成模型pwiz.py、Schema 遷移playhouse/migrate.py、連接池playhouse/pool.py、跨庫反射playhouse/reflection.py、數據庫 URLplayhouse/db_url.py、測試工具playhouse/test_utils.py與 Flask 集成playhouse/flask_utils.py。真實項目示例倉庫examples/目錄下提供了多個可直接運行的完整應用examples/twitter/app.pyREADME 中推薦的 Twitter 風格 Web 應用演示了BaseModel模式、自引用外鍵用戶關注關系、CharField(uniqueTrue)用戶名字段以及該用戶關注了誰 / 誰關注了該用戶這類多表 JOIN 查詢examples/blog/app.py基于 Flask Peewee 的博客應用使用playhouse.flask_utils.FlaskDB管理請求級數據庫連接sqliteext:///數據庫 URL 接入 SQLite 擴展并展示了BooleanField(indexTrue)、DateTimeField(defaultdatetime.datetime.now, indexTrue)等帶索引字段的建模方式其他單文件示例如 examples/diary.py加密命令行日記、examples/adjacency_list.py鄰接表樹、examples/graph.py圖算法、examples/anomaly_detection.py異常檢測等展示了 Peewee 在不同場景下的靈活性。對接現有數據庫pwiz如果已有現成數據庫可用 pwiz 自動生成模型代碼python -m pwiz -e postgresql charles_blog blog_models.py-e指定數據庫引擎如sqlite、mysql、postgresqlpwiz 會通過反射playhouse/reflection.py讀取表結構、字段類型、外鍵與索引輸出可直接使用的模型定義。對應的集成測試見 tests/pwiz_integration.py。社區(qū)與進一步學習完整文檔與更多示例見倉庫 docs 目錄從 docs/index.rst 開始瀏覽查詢進階聚合、CTE、窗口函數、復合查詢等大量實例位于 docs/peewee/querying.rst 與 docs/peewee/query_examples.rst測試體系倉庫自帶覆蓋完善的測試集tests可運行 runtests.py 執(zhí)行tests/base.py提供了針對 SQLite/MySQL/PostgreSQL 的統一測試基類性能對比倉庫提供了 bench.py 基準腳本可用于對比 select/insert/bulk 等常見操作耗時。結語從 README 的一個 Tweet 示例出發(fā)本文完整走通了 Peewee 的建模、建表、寫入、查詢、JOIN、聚合、分頁與原子更新全流程并用倉庫源碼、擴展清單與真實示例做了印證。Peewee 的核心設計哲學是概念少而精——掌握本文的模型與查詢模式你就能覆蓋絕大多數日常數據庫操作需要更高級能力時playhouse擴展與完整文檔隨時可以繼續(xù)深入。【免費下載鏈接】peeweea small, expressive orm -- supports postgresql, mysql, sqlite, now with asyncio項目地址: https://gitcode.com/gh_mirrors/pe/peewee創(chuàng)作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考