我刚开始一个名为flask_wiki的简单项目,我使用了一些烧瓶扩展,如下所示:
好吧,我刚刚发现MarshMallow项目提供了一个名为' ModelSchema'的类,它从我的SQLAlchemy模型中读取所有字段并提供一个完全自动化的(de)序列化器。
在我的情况下,我创建了一个' GUID'与RDBM无关的字段并将其插入我的Sqlalchemy模型,如下所示:
echo $query;
GUIDField以这种方式实现:
from flask.ext.sqlalchemy import SQLAlchemy
from flask_wiki.backend.custom_fields import GUIDField
class Page(db.Model):
"""
Implements the Page Model.
"""
guid = db.Column(GUIDField, primary_key=True, default=uuid.uuid4)
name = db.Column(db.String, nullable=False)
raw_content = db.Column(db.Text)
rendered_content = db.Column(db.Text)
def __repr__(self):
return self.__str__()
def __str__(self):
return self.name
创建测试对象的代码(通过混音器)正在运行;所有的guid都是正确生成和验证的。
考虑到这一点,刚刚创建了以下MarshMallow Serializer字段:
from sqlalchemy.types import TypeDecorator, CHAR
import uuid
class GUIDField(TypeDecorator):
# Platform independent GUID Implementation that uses little endianess.
impl = CHAR
def load_dialect_impl(self, dialect):
return dialect.type_descriptor(CHAR(32))
def process_bind_param(self, value, dialect):
if value is None:
return value
else:
if isinstance(value, uuid.UUID):
return value.bytes_le
def process_result_value(self, value, dialect):
if value is None:
return value
else:
return uuid.UUID(bytes_le=value)
最后,我创建了SerializerClass:
from marshmallow import fields
import uuid
class GUIDSerializationField(fields.Field):
def _serialize(self, value, attr, obj):
if value is None:
return value
else:
if isinstance(value, uuid.UUID):
return str(value)
else:
return None
我尝试使用和不插入guid字段的最后一个代码,但在所有情况下都会发生以下错误:
from flask_wiki.backend.backend import marsh
from flask_wiki.backend.custom_serialization_fields import GUIDSerializationField
from flask_wiki.backend.models import Page
from marshmallow import fields
class PageSchema(marsh.ModelSchema):
class Meta:
model = Page
guid = GUIDSerializationField()
page_schema = PageSchema()
pages_schema = PageSchema(many=True)
所以,我终于问:如何使用marshmallow序列化自定义sqlalchemy字段?
答案 0 :(得分:7)
您需要创建自己的转换器。 尝试这样的事情:
import uuid
from flask_wiki.backend.models import Page
from flask_wiki.backend.backend import marsh
from marshmallow_sqlalchemy.convert import ModelConverter
from flask_wiki.backend.custom_fields import GUIDField
from marshmallow import fields
#Here you are overwriting the list of types of the SQLAlchemy, adding your custom type
class GUIDConverter(ModelConverter):
SQLA_TYPE_MAPPING = dict(
list(ModelConverter.SQLA_TYPE_MAPPING.items()) +
[(GUIDField, fields.Str)]
)
class GUIDSerializationField(fields.Field):
def _serialize(self, value, attr, obj):
if value is None:
return value
else:
if isinstance(value, uuid.UUID):
return str(value)
else:
return None
class PageSchema(marsh.ModelSchema):
class Meta:
model = Page
model_converter = GUIDConverter #Tell to Marshmallow to use your custom converter for this model
guid = GUIDSerializationField(attribute="guid")
您还可以查看this链接以获取帮助。 我希望它对我糟糕的英语有帮助和抱歉
答案 1 :(得分:2)
根据我在文档中阅读的内容,您可以在ModelSchema
Meta class中指定一个model_converter属性。 ModelConverter
class具有select *
from posts left outer join
votes on
votes.votable_id = posts.id and
votes.votable_type = 'Posts' and
votes.user_id = 16 ---> (My user_id)
where posts.user_id = 21 ---> (user_id i'm looking at)
属性,您可以在子类中覆盖该属性,以将自定义GUID字段添加到自动架构生成器检测到的类型中。
那就是说,我从未使用它,所以我不知道这是否有用。