当我添加了一个关联表时,使用模式序列化Joke数据时遇到了问题.

这是我的模型,它允许用户输入一个Jest ,也可以输入一个标签来对Jest 进行分类:

class Joke(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    joke_name = db.Column(db.String(40), nullable=False)
    joke = db.Column(db.String(5000), nullable=False)
    joke_owner = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    joke_category = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=True)
    joke_created = db.Column(db.DateTime, nullable=True)
    joke_edited = db.Column(db.DateTime, nullable=True)
    tags = db.relationship('JokeTag', secondary=tag_joke, backref=db.backref('jokes', lazy='dynamic'), lazy='dynamic',
            primaryjoin=tag_joke.c.joke_id==id,
            secondaryjoin=tag_joke.c.joketag_id==JokeTag.id)


class JokeTag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    tag = db.Column(db.String(25), nullable=False)
    tag_owner = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)


下面是我的关联表,它以多对多的方式将两者连接起来:


tag_joke = db.Table('tag_joke', 
        db.Column('joke_id', db.Integer, db.ForeignKey('joke.id')),
        db.Column('joketag_id', db.Integer, db.ForeignKey('joke_tag.id'))
        )

我正在try 使用以下架构来序列化数据:

class TagJokeSchema(ma.Schema):
    class Meta:
        fields = ('joke_id', 'joketag_id')



class JokeSchema(ma.Schema):
    class Meta:
        fields = ('id', 'joke_name', 'joke', 'joke_owner', 'joke_category', 'joke_created', 'joke_edited', 'tags')

        tags=ma.Nested(TagJokeSchema, many=True)


我在模式上做了一些错误的事情,因为当我try 用以下代码序列化数据时:

allnotes = Joke.query.filter_by(joke_owner=1).all()
result = jokes_schema.dump(allnotes)


我得到以下TypeError:

TypeError: Object of type AppenderBaseQuery is not JSON serializable

当我try 从python命令行访问Jest 和标记时,我能够访问Jest 和相应的标记.尽管当我试着发表一个Jest 时,它确实看起来有点疯狂:

Joke('35','No reason','Finance people get buff for no reason.  Just to work on Excel spreadsheets.','1','55', None, None, SELECT joke_tag.id AS joke_tag_id, joke_tag.tag AS joke_tag_tag, joke_tag.tag_owner AS joke_tag_tag_owner 
FROM joke_tag, tag_joke 
WHERE tag_joke.joke_id = %s AND tag_joke.joketag_id = joke_tag.id)


我希望得到一个更干净的 fingerprint ,如果他们有的话,里面嵌有标签.

编辑@Greg0ry: 所有备注的打印输出如下所示:

[Joke('25','Test Joke','Knock, Knock, Whos There, test joke','1','55', None, None, SELECT joke_tag.id AS joke_tag_id, joke_tag.tag AS joke_tag_tag, joke_tag.tag_owner AS joke_tag_tag_owner FROM joke_tag, tag_joke WHERE tag_joke.joke_id = %s AND tag_joke.joketag_id = joke_tag.id), Joke('35','No reason','Finance people get buff for no reason.  Just to work on Excel spreadsheets.','1','55', None, None, SELECT joke_tag.id AS joke_tag_id, joke_tag.tag AS joke_tag_tag, joke_tag.tag_owner AS joke_tag_tag_owner FROM joke_tag, tag_joke WHERE tag_joke.joke_id = %s AND tag_joke.joketag_id = joke_tag.id)]

在我Joke岁的班级里,我也有这个解释打印出来的东西,我从YouTube上的一个教程中得到了这个,我觉得我相信(科里·谢弗):

    def __repr__(self):
        return f"Joke('{self.id}','{self.joke_name}','{self.joke}','{self.joke_owner}','{self.joke_category}', {self.joke_created}, {self.joke_edited}, {self.tags})"

至于db.Model,我可能不理解您在寻找什么,但我有以下内容:

app = Flask(__name__)
db = SQLAlchemy(app)

希望有一种方法可以指导我更多地了解你正在寻找的东西?

另外,如果我想找一个特定的Jest ,

jokequery = Joke.query.filter_by(joke_owner=1, id=595).first()

我得到

Joke('595','test joke','knock knock whos there test joke','1','475', None, None, SELECT joke_tag.id AS joke_tag_id, joke_tag.tag AS joke_tag_tag, joke_tag.tag_owner AS joke_tag_tag_owner 
FROM joke_tag, tag_joke 
WHERE tag_joke.joke_id = %s AND tag_joke.joketag_id = joke_tag.id)

显然,最后一部分看起来相当糟糕.这是因为tagsAppenderBaseQuery

但如果我运行这个:

jokequery.tags.all()

输出看起来很棒,是一个JSON可序列化的列表:

[JokeTag('45', 'stackoverflow', '1')]

但是,如何设置才能发送要序列化的列表而不是查询呢?

推荐答案

问题是这段关系上的lazy='dynamic'setting

...将为所有读取操作返回预配置的查询对象...

我们可以删除此设置(也可以替换传统的backref):


# Some columns removed for brevity and readability.

class JokeTag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    tag = db.Column(db.String(25), nullable=False)
    tag_owner = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    jokes = db.relationship('Joke', secondary='tag_joke', back_populates='tags')


class Joke(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    joke_name = db.Column(db.String(40), nullable=False)
    joke = db.Column(db.String(5000), nullable=False)
    joke_owner = db.Column(
        db.Integer, db.ForeignKey('user.id'), nullable=False
    )
    tags = db.relationship(
        'JokeTag',
        secondary=tag_joke,
        back_populates='jokes'
    )

如果您希望保留lazy='dynamic'设置,则可以对序列化输出进行后处理,以获得查询结果:

...
class JokeSchema(ma.Schema):
    class Meta:
        fields = (
            'id',
            'joke_name',
            'joke',
            'joke_owner',
            'joke_category',
            'joke_created',
            'joke_edited',
            'tags',
        )

        tags = ma.fields.Nested(TagJokeSchema, many=True)

    # Assuming ma in the question is Marshmallow

    @ma.post_dump
    def dump_tags(self, obj, **kw):
        obj['tags'] = [t.name for t in obj['tags'].all()]
        return obj

Python相关问答推荐

如何在句子之间添加空白但忽略链接?

Tkinter滑动条标签.我不确定如何删除滑动块标签或更改其文本

在matplotlib动画gif中更改配色方案

在上下文管理器中更改异常类型

使用pandas、matplotlib和Yearbox绘制时显示错误的年份

在函数内部使用eval(),将函数的输入作为字符串的一部分

Select 用a和i标签包裹的复选框?

如何使用pandasDataFrames和scipy高度优化相关性计算

Polars LazyFrame在收集后未返回指定的模式顺序

ModuleNotFound错误:没有名为Crypto Windows 11、Python 3.11.6的模块

rame中不兼容的d类型

使用miniconda创建环境的问题

将两只Pandas rame乘以指数

聚合具有重复元素的Python字典列表,并添加具有重复元素数量的新键

使用@ guardlasses. guardlass和注释的Python继承

Streamlit应用程序中的Plotly条形图中未正确显示Y轴刻度

Stacked bar chart from billrame

如果满足某些条件,则用另一个数据帧列中的值填充空数据帧或数组

为一个组的每个子组绘制,

Python—转换日期:价目表到新行