首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用棉花糖序列化自定义sqlalchemy字段?

如何使用棉花糖序列化自定义sqlalchemy字段?
EN

Stack Overflow用户
提问于 2015-10-16 00:40:53
回答 2查看 9.2K关注 0票数 5

我今天刚刚开始了一个名为flask_wiki的简单项目,我使用了一些烧瓶扩展,如下所示:

  • 瓶-SQLAlchemy
  • 烧瓶-休息
  • MarshMallow

我刚刚发现,MarshMallow项目提供了一个名为“ModelSchema”的类,它从我的SQLAlchemy模型中读取所有字段,并提供一个完全自动化(反)序列化器。

在我的例子中,我创建了一个“GUID”字段,它与RDBM无关,并将其插入到我的Sqlalchemy模型中,如下所示:

代码语言:javascript
运行
复制
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

GUIDField是这样实现的:

代码语言:javascript
运行
复制
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)

创建测试对象的代码(通过混频器)正在工作;所有and都被正确地生成和验证。

考虑到这一点,刚刚创建了以下MarshMallow序列化器字段:

代码语言:javascript
运行
复制
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

最后,我创建了SerializerClass:

代码语言:javascript
运行
复制
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)

我尝试在插入guid字段和不插入guid字段时使用最后一段代码,但在所有情况下都会发生以下错误:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "/home/arthas/dev/flask-wiki/flask_wiki/wiki.py", line 3, in <module>
    from flask_wiki.backend import backend
  File "/home/arthas/dev/flask-wiki/flask_wiki/backend/__init__.py", line 1, in <module>
    import flask_wiki.backend.routes
  File "/home/arthas/dev/flask-wiki/flask_wiki/backend/routes.py", line 2, in <module>
    from flask_wiki.backend.views import PageView
  File "/home/arthas/dev/flask-wiki/flask_wiki/backend/views.py", line 3, in <module>
    from flask_wiki.backend.serializers import pages_schema, page_schema
  File "/home/arthas/dev/flask-wiki/flask_wiki/backend/serializers.py", line 7, in <module>
    class PageSchema(marsh.ModelSchema):
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow/schema.py", line 116, in __new__
    dict_cls=dict_cls
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow_sqlalchemy/schema.py", line 53, in get_declared_fields
    declared_fields = mcs.get_fields(converter, opts)
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow_sqlalchemy/schema.py", line 77, in get_fields
    return converter.fields_for_model(opts.model, fields=opts.fields, exclude=opts.exclude)
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow_sqlalchemy/convert.py", line 75, in fields_for_model
    field = self.property2field(prop)
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow_sqlalchemy/convert.py", line 93, in property2field
    field_class = self._get_field_class_for_property(prop)
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow_sqlalchemy/convert.py", line 151, in _get_field_class_for_property
    field_cls = self._get_field_class_for_column(column)
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow_sqlalchemy/convert.py", line 121, in _get_field_class_for_column
    return self._get_field_class_for_data_type(column.type)
  File "/home/arthas/env/wiki/lib/python3.5/site-packages/marshmallow_sqlalchemy/convert.py", line 143, in _get_field_class_for_data_type
    'Could not find field column of type {0}.'.format(types[0]))
marshmallow_sqlalchemy.exceptions.ModelConversionError: Could not find field column of type <class 'flask_wiki.backend.custom_fields.GUIDField'>.

因此,我最后问:如何使用棉花糖序列化自定义sqlalchemy字段?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-18 21:48:26

你需要创建你自己的转换器。试着做这样的事情:

代码语言:javascript
运行
复制
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")

您还可以看到链接以获得帮助。我希望它能帮助我,为我糟糕的英语感到遗憾

票数 8
EN

Stack Overflow用户

发布于 2015-10-16 17:54:17

根据我在文档中看到的内容,您可以在您的model_converter中指定一个元类属性。班级有一个SQLA_TYPE_MAPPING属性,可以在子类中重写,以便将自定义GUID字段添加到自动模式生成器检测到的类型中。

尽管如此,我从来没有用过它,所以我不知道这样做是否有效。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33160762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档