摘要:下面我們來說說如何使用來減輕序列化模型的工作量。主要包括如下個步驟定義模式序列化模型下面我們分別來看看。不得不說這個庫對于序列化模型其實挺實用的。
原文地址:
http://52sox.com/use-python-serialization-orm-data-to-json/
相信使用Python做Web開發的朋友都會遇到這樣1個問題,那就是在項目開發中使用模型框架,比如SQLAlchemy、Peewee,我們在做RESTful接口時如何將這些模型序列化為JSON數據。
關于這個問題,跟隔壁那位搞Python的哥們有關系。我不得不佩服這位哥們竟然自己寫了1套ORM框架,而且用起來的那么遛,不得不讓我汗顏。
但是,在給前端提供接口的時候,如何序列化為JSON數據確實困擾了我們那么一陣子,畢竟占據我們很大一部分時間來進行序列化操作。
這里,我們使用peewee來定義1個簡單的例子來說明:
from peewee import SqliteDatabase from peewee import Model, CharField, DateField, BooleanField, ForeignKeyField db = SqliteDatabase("dev.sqlite3") class BaseModel(Model): class Meta: database = db class Person(BaseModel): name = CharField(max_length= 20) birthday = DateField() sex = BooleanField() class Pet(BaseModel): owner = ForeignKeyField(Person, related_name= "pets") name = CharField(max_length= 10) animal_type = CharField(max_length= 20)
在這里我們定義了Person和Pet這2個模型,每個Person可能有1個Pet的寵物。
我們插入一些數據,現在假設我們現在有如下的數據:
sqlite> select * from person; 1|Bob|1960-01-15|1 2|Grandma|1935-03-01|0 3|Herb|1950-05-05|1 sqlite> select * from pet; 1|1|Kitty|cat 2|3|Fido|dog 3|3|Mittens|cat 4|2|Jack|cat
現在,我們假設我們接口需要返回的接口是每個用戶的名稱、生日及其對應的寵物的信息。
我們可以通過連表的方式輕松的獲取到我們需要的數據:
query=Person.select(Person,Pet).join(Pet)
那么我們怎么將這個模型數據轉換為我們需要的JSON數據呢?一般情況下,我們會這樣操作:
data = [] for person in query.aggregate_rows(): d={} d["username"] = person.name d["birthday"] = person.birthday d["pet"] = [] for pet in person.pets: o = {} o["name"] = pet.name o["animal_type"] = pet.animal_type d["pet"].append(o) data.append(d)
最后我們將得到如下的結果:
[{"birthday": datetime.date(1960, 1, 15), "pet": [{"animal_type": u"cat", "name": u"Kitty"}], "username": u"Bob"}, {"birthday": datetime.date(1950, 5, 5), "pet": [{"animal_type": u"dog", "name": u"Fido"}, {"animal_type": u"cat", "name": u"Mittens"}], "username": u"Herb"}, {"birthday": datetime.date(1935, 3, 1), "pet": [{"animal_type": u"cat", "name": u"Jack"}], "username": u"Grandma"}]
可以看到,這么1個簡單的例子,我們已經對序列化操作處理的已經夠嗆的。對于那些更為復雜的模型,我們預計只有哭的份了。
因此,我們希望能找到1個庫可以減輕我們的工作量,于是我們找到了1個marshallow的庫。
下面我們來說說如何使用marshallow來減輕序列化模型的工作量。
主要包括如下2個步驟:
定義模式
序列化模型
下面我們分別來看看。
定義模式如果你使用過Flask-RESTful,你應該知道該庫提供了1個marshal_with的函數。其中我們就需要定義我們給定字段返回的數據類型,但是Flask-RESTful沒有提供字段不同返回的操作。
我們通過如下的方式導入模式及其對應的字段:
from marshmallow import Schema, fields
接下來,我們定義1個繼承自Schema的類,然后定義其對應的字段:
class PetSchema(Schema): name = fields.String() animal_type = fields.String() class PersonSchema(Schema): name = fields.String(dump_to = "username") birthday = fields.Date() pets = fields.Nested(PetSchema,dump_to="pet",many=True)
由于這里,我們將用戶的name屬性修改為username,因此我們需要在字段中使用dump_to參數將其修改為我們需要的字段。另外,用戶的pet字段對應的是寵物的信息,因此我們采用嵌套模式來實現這樣需求。
序列化模型上面我們已經定義好了我們的模式了,下一步是序列化模型的操作了。
我們可以這樣來操作:
query=Person.select(Person, Pet).join(Pet)
接著,我們實例化我們的模式,然后傳入需要序列化的模型:
person, error = PersonSchema(many = True).dumps(query.aggregate_rows())
在這里,我們調用PersonSchema實例的dumps來生成JSON數據,另外它還有1個dump方法用于生成Python對象。由于我們的渲染的數據有多條,因此我們需要在實例化PersonSchema類時傳入關鍵字參數many為True,不然沒有任何數據。
通過這種方式,PersonSchema會查看它自己的屬性,將數據模型中對應的數據先序列化出來,然后是查詢嵌套模式中的字段,如果符合對應的名稱則將其序列化出來,最后我們將得到這樣的數據:
[ { "username": "Bob", "pet": [ { "animal_type": "cat", "name": "Kitty" } ], "birthday": "1960-01-15" }, { "username": "Herb", "pet": [ { "animal_type": "dog", "name": "Fido" }, { "animal_type": "cat", "name": "Mittens" } ], "birthday": "1950-05-05" }, { "username": "Grandma", "pet": [ { "animal_type": "cat", "name": "Jack" } ], "birthday": "1935-03-01" } ]
可以看到,通過marshallow得到的結果與之前我們編寫的序列化操作的結果是一樣的。
不得不說,marshallow這個庫對于序列化模型其實挺實用的。當然對于復雜的模型,我們需要利用合適的方式將其搜索出來,不然還是序列化不了的。
參考文章:
https://marshmallow.readthedocs.io/en/latest/quickstart.html
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/38028.html
摘要:據公告稱,和的包裝庫使用了不安全的函數來反序列化編碼的機器學習模型。簡單來看,序列化將對象轉換為字節流。據悉,本次漏洞影響與版本,的到版本均受影響。作為解決方案,在宣布棄用之后,團隊建議開發者以替代序列化,或使用序列化作為替代。 ...
摘要:在本文中,我們將學習構建自定義新聞語料庫并分別注釋與興趣相對應的大量文章。為此,我們將使用。我們將使用另一個名為的免費服務。我正在使用單擊創建觸發器完成。我們將使用相同的調度庫來運行我們在第章構建應用程序以查找廉價機票中使用的代碼。 showImg(https://segmentfault.com/img/remote/1460000019191794); 來源 | 愿碼(Chain...
摘要:查詢集表示從數據庫中取出來的對象的集合。例如,返回包含數據庫中所有對象的一個查詢集。最后的結果仍然是一個查詢集,它包含標題以開頭發布日期在年月日至當天之間的所有記錄。一般來說,只有在請求查詢集的結果時才會到數據庫中去獲取它們。 Django數據庫操作 創建對象 Django 使用一種直觀的方式把數據庫表中的數據表示成Python 對象: 一個模型類代表數據庫中的一個表,一個模型類的實...
摘要:方法對應的是方法,它反序列化一個字典為數據結構。某些例如和內置了驗證器驗證集合時,錯誤字典將基于無效字段的索引作為鍵通過給的參數傳遞對象,可以執行額外的驗證驗證函數可以返回布爾值或拋出異常。 快速上手 Declaring Schemas 首先創建一個基礎的user模型(只是為了演示,并不是真正的模型): import datetime as dt class User(object)...
閱讀 3417·2021-11-24 09:38
閱讀 3194·2021-11-22 09:34
閱讀 2108·2021-09-22 16:03
閱讀 2368·2019-08-29 18:37
閱讀 380·2019-08-29 16:15
閱讀 1770·2019-08-26 13:56
閱讀 866·2019-08-26 12:21
閱讀 2207·2019-08-26 12:15