'RelationshipProperty'对象不可迭代 - Flask Api - sqlalchemy

时间:2018-05-14 19:18:06

标签: python flask flask-sqlalchemy

:)

我开发了一个带有膳食价格计算的Android Cook-App。

我几乎完成了我的Api,但现在我得到了一个TypeError:'RelationshipProperty'对象不可迭代。

我挣扎着我的总和(饭团价格)我有我的json,但我喜欢查询我的饭菜

@classmethod
def find_by_mealprice(cls, mealprice):
    return cls.query.filter_by(mealprice=mealprice).first()

但我只能用json方法构建我的总和。

class MealModel(db.Model):

__tablename__ = 'meal'

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
description = db.Column(db.String)
usp = db.Column(db.String)
workTime = db.Column(db.TIME)
mainIngredients =db.Column(db.String)
img = db.Column(db.String)

difficulty_id = db.Column(db.Integer, db.ForeignKey('difficulty.id'))
difficulty = db.relationship('DifficultyModel')

diet_id = db.Column(db.Integer, db.ForeignKey('diet.id'))
diet = db.relationship('DietModel')

category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
category = db.relationship('CategoryModel')

recipes = db.relationship('RecipeModel', lazy="dynamic")

mealprice = (sum([(recipe.ingredients.price/recipe.ingredients.minamount * recipe.quantity) for recipe in recipes])) <-- TypeError?


def __repr__(self):
    return (self.name)



def json(self):

    mealprice = (sum([(recipe.ingredients.price/recipe.ingredients.minamount * recipe.quantity) for recipe in self.recipes]))

    return {    'id': self.id, 
                'name': self.name, 
                'mIng': self.mainIngredients, 
                'usp': self.usp,
                'difficulty': self.difficulty.name,
                'workTime': self.workTime.isoformat(),
                'diet': self.diet.name,
                'description': self.description,
                'mealImage': self.img,
                'category': self.category.name,
                'recipes': [recipe.json() for recipe in self.recipes],
                'meal_price': mealprice
            }

我希望这个问题不是愚蠢的,我是Flask Api和Python的新手,我几个月前用Android Studio编程。

希望你能帮忙! :)我如何用mealprice查询?

1 个答案:

答案 0 :(得分:0)

简短回答:

您没有在列表中包含要查询的列。

答案很长:

SQLAlchemy帮助您转换驻留在数据库中的模型,将它们移动到python代码中的类中,这样两者都可以非常神奇地进行交互。您可以使用python扩展使用SQLAlchemy生成的模型,就像在声明mealprice和json时一样。您也可以重载现有属性,就像使用 repr

一样

为了能够查询属性,你必须使它成为SQLAlchemy意义上的一个属性,这是一个列。当你这样做时:

category_id = db.Column(db.Integer, db.ForeignKey('category.id'))

您可以在python中基于db.Column创建category_id属性,该属性是SQLAlchemy属性,因此您可以对其进行查询。

换句话说,如果你这样做:

mealprice = db.Column(db.Numeric, default=calc_mealprice, onupdate=calc_mealprice)

您可以根据需要定义自己的功能,http://docs.sqlalchemy.org/en/latest/core/defaults.html

这将使您的餐价可查询,因为它现在是一个专栏。但是,在当前数据库状态下使用函数时会出现问题,因为您的餐饮价格是查询结果中的列数之和。

您收到的错误TypeError是因为您将查询与数字混合,并且在构造对象后对它们进行评估。所以recipe.ingredients.price是一个查询,当你定义mealprice(在施工期间),但在json期间成为一个列表。

修改

就个人而言,我会将问题分开并避免使用混合属性,因为它们可能会模糊数据库和python之间的限制。如果你的成分可能会改变,我会做类似的事情:

def calc_price_by_minamount(context):
    price = context.get_current_parameters()['price']
    minamount = context.get_current_parameters()['minamount']
    return price / ingredient.minamount

class IngredientModel(db.Model):
    ...
    price_by_minamount = db.Column(db.Numeric,
                                   default=calc_price_by_minamount, 
                                   onupdate=calc_price_by_minamount)

def calc_price(context):
    ingredients = context.get_current_parameters()['ingredients']
    quantity = context.get_current_parameters()['quantity']
    return sum([ingredient.price_by_minamount 
                for ingredient 
                in ingredients]) * quantity

class RecipeModel(db.Model):
    ...
    price = db.Column(db.Numeric, 
                      default=calc_price, 
                      onupdate=calc_price)

def calc_mealprice(context):
    recipes = context.get_current_parameters()['recipes']
    return sum([recipe.price for recipe in recipes])

class MealModel(db.Model):
    ...
    mealprice = db.Column(db.Numeric, 
                          default=calc_mealprice, 
                          onupdate=calc_mealprice)

如果需要,您可以从那里开始实现混合属性。