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