如何从Flask-SQLAlchemy关系查询返回序列化的JSON?

时间:2018-03-19 21:10:55

标签: python json sqlalchemy flask-sqlalchemy

我正在使用Flask-SQLAlchemy,我有以下具有一对多关系的模型,

def longestPalindrome(self, s):
    # write your code here
    if len(s) == 0 or len(s) == 1:
        return s
    else:
        def ispalindrome(k):
            while k[0] == k[-1]:
                k = k[1:-1]
            if len(k) > 1:
                return False
            else:
                return True
        for i in s:
            if s.rfind(i) > s.find(i):
                s = s[s.find(i):s.rfind(i)+1]
            if ispalindrome(s) == True:
                break
                return s
            else:
                s = s[1:-1]

我希望像这样返回JSON:

class User(db.Model):

    # Table name
    __tablename__ = "users"

    # Primary key
    user_id = db.Column(db.Integer, primary_key=True)

    # Fields (A-Z)
    email = db.Column(db.String(50), nullable=False, unique=True)
    password = db.Column(db.String, nullable=False)
    username = db.Column(db.String(50), unique=True)

    # Relationships (A-Z)
    uploads = db.relationship("Upload", backref="user")

class Upload(db.Model):

    # Table name
    __tablename__ = "uploads"

    # Primary key
    upload_id = db.Column(db.Integer, primary_key=True)

    # Fields (A-Z)
    name = db.Column(db.String(50), nullable=False)
    path_to_file = db.Column(db.String(256), nullable=False, unique=True)
    uploaded_by = db.Column(db.Integer, db.ForeignKey("users.user_id"))

所以基本上我想用数组中的所有上传(用户上传的文件)返回用户对象。

我知道我可以使用User.uploads(使用db.relationship创建)访问用户内的上传类对象,但我需要某种序列化器。

我想为我的所有模型添加自定义serialize()方法:

{
    "users": [
        {
            "email": "vargovcik.marek@gmail.com",
            "uploads": [
                {
                    "name": "1.png",
                    "path_to_file": "static/1.png"
                }
            ],
            "username": "maro"
        },
        {
            "email": "makos@gmail.com",
            "uploads": [
                {
                    "name": "2.jpg",
                    "path_to_file": "static/2.jpg"
                }
            ],
            "username": "makos"
        }
    ]
}

但问题是我最终得到了嵌套循环。我的用户对象有上传文件,每次上传都有用户的数据,这些用户的数据上传文件......

我的观点端点:

# User serializer
    def serialize_user(self):
        if self.uploads:
            uploads = [upload.serialize_upload() for upload in self.uploads]
        return {
            "email": self.email,
            "password": self.password,
            "username": self.username,
            "uploads": uploads
        }

# Upload serializer
    def serialize_upload(self):
        if self.user:
            dict_user = self.user.serialize_user()
        return {
            "name": self.name,
            "path_to_file": self.path_to_file,
            "user": dict_user
        }

错误:

@app.route('/users', methods=["GET"])
def get_users():
    users = [user.serialize_user() for user in User.query.all()]
    return jsonify(users)

部分解决方案:

我可以简单地省略在上传序列化程序中序列化用户对象,但是我将无法创建类似的端点但是无法上传。 示例:/ uploads - 包含所有上传和嵌套用户对象的JSON。

如何有效地处理关系以将它们作为与上述JSON结构类似的序列化JSON数据返回?

1 个答案:

答案 0 :(得分:0)

正如您所说,您可以简单地编写第二个serializer方法。所以你保留另一个用于/ uploads API调用。

# User serializer
def serialize_user(self):
    if self.uploads:
        uploads = [upload.serialize_upload_bis() for upload in self.uploads]
    return {
            "email": self.email,
            "password": self.password,
            "username": self.username,
            "uploads": uploads
    }

# Upload serializer
def serialize_upload_bis(self):
    return {
        "name": self.name,
        "path_to_file": self.path_to_file,
    }

def serialize_upload(self):
    if self.user:
        dict_user = self.user.serialize_user()
    return {
        "name": self.name,
        "path_to_file": self.path_to_file,
        "user": dict_user
    }