亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 SQLAlchemy TypeDecorator 時 Marshmallow 驗證錯誤地失敗

使用 SQLAlchemy TypeDecorator 時 Marshmallow 驗證錯誤地失敗

米脂 2022-12-27 15:42:26
我創建了一個基于SQLAlchemy 示例的 TypeDecorator ,它在 32 個字符的十六進制字符串和BINARY存儲 UUID 的數據庫列之間進行轉換:from __future__ import absolute_importimport uuidfrom sqlalchemy import types, func#https://docs.sqlalchemy.org/en/13/core/custom_types.html#backend-agnostic-guid-typeclass HashColumn(types.TypeDecorator):    impl=types.BINARY    def process_bind_param(self, value, dialect):        if value is not None:            return uuid.UUID(hex=value).bytes    def process_result_value(self, value, dialect):        return uuid.UUID(bytes=value).hex    def copy(self, **kw):        return HashColumn(self.impl.length)模型:def get_uuid():    return uuid.uuid4().hexclass School(db.Model):    """        description: A School    """    __tablename__ = "schools"    id = db.Column('school_id', HashColumn(length=16), primary_key=True, default=get_uuid)    ...但是,我遇到的問題是我的棉花糖模式(從 SQLAlchemy 模型生成)沒有將此列視為 32 個字符的字符串:架構:from marshmallow_sqlalchemy import SQLAlchemyAutoSchema...class SchoolSchema(SQLAlchemyAutoSchema):    class Meta:        model = School        include_relationships = True        load_instance = True        include_fk = True...在我的代碼中:try:    new_object = SchoolSchema().load(data, session=db.session)except ValidationError as err:    print(err.messages)    print(err.valid_data)當使用完全有效的 UUID 運行此代碼時a5fad20c691546ae8871390d980aae6d,marshmallow 會拋出驗證錯誤并提供以下輸出:{"id": ["Longer than maximum length 16."]}由于我想在使用過程中將 UUID 格式化為 32 個字符的十六進制字符串(或適用的 python UUID),并BINARY(16)在存儲到數據庫之前轉換為正確的格式,因此我需要消除此驗證錯誤,但我不確定如何做到這一點,因為更改 SQLAlchemy 模型上的長度參數將意味著將創建數據庫表BINARY(32)而不是BINARY(16),將長度加倍。是否可以設置 SQLAlchemyTypeDecorator以便它在數據庫中存儲一種長度 ( BINARY(16)) 的類型,但向CHAR(32)Python 和/或 SQLAlchemy 提供不同的長度 ( ) 以便 marshmallow 可以正確地將長度驗證為 32 個字符的字符串?
查看完整描述

1 回答

?
holdtom

TA貢獻1805條經驗 獲得超10個贊

到目前為止,我找到了兩種方法來解決這個問題:


調整 TypeDecorator 的類型,使其像CHAR列而不是二進制列一樣工作,并用于load_dialect_impl更改呈現給數據庫的類型,指定不同的長度作為參數


class HashColumn(types.TypeDecorator):

    impl=types.CHAR


    def load_dialect_impl(self, dialect):

        return dialect.type_descriptor(types.BINARY(16))


   ...

(課程的其余部分與問題中的內容基本相同)


此更改允許我將HashColumn(length=16)定義從我的 DB 模型更改為HashColumn(length=32),從而允許 marshmallow 正確解釋長度。


或者,我可以更改我的 API PATCH/更新端點的實現以從數據庫中獲取和更新現有對象,而不是創建一個全新的對象并嘗試合并它們的值。這完全刪除了 Marshmallow 驗證,因為 ID 不再用于創建新對象,但是,對我來說,這感覺像是一種太多的解決方法,并且意味著,因為沒有使用 Marshmallow 驗證,它也不會驗證任何其他數據字段。


查看完整回答
反對 回復 2022-12-27
  • 1 回答
  • 0 關注
  • 103 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號