Sqlalchemy 一对多关系连接?

6 投票
1 回答
15046 浏览
提问于 2025-04-18 02:27

我正在尝试做一个简单的连接查询,像这样:

SELECT food._id, food.food_name, food_categories.food_categories FROM food JOIN food_categories ON food.food_category_id = food_categories._id

但是我总是收到一个错误。下面是我的类是怎么设置的。

class Food_Categories(db.Model):
    __tablename__ = 'food_categories'
    _id = db.Column(db.Integer, primary_key=True)
    food_categories = db.Column(db.String(30))

class Food(db.Model):
    __tablename__ = 'food'
    _id = db.Column(db.Integer, primary_key=True)
    food_name = db.Column(db.String(40))
    food_category_id = db.Column(db.Integer, ForeignKey(Food_Categories._id))
    food_category = relationship("Food_Categories")

我的查询函数看起来是这样的。

@app.route('/foodlist')
def foodlist():
    if request.method == 'GET':
        results = Food.query.join(Food_Categories.food_categories).all()

    json_results = []
    for result in results:
        d = {'_id': result._id,
         'food': result.food_name,
         'food_category': result.food_categories}
    json_results.append(d)

    return jsonify(user=json_results)

我在使用Flask。当我调用这个路由时,我得到了这个错误。

AttributeError: 'ColumnProperty' object has no attribute 'mapper'

我其实想要的是这个:

|      id       |    food_name    |    food_category    |

并且希望将food_category_id这一列替换成其他表中实际的食物类别名称。

我的表和关系设置正确吗?我的查询设置正确吗?

1 个回答

6

你的表格和关系设置得很正确,但你的查询需要调整一下。

出现错误的原因是你试图在一个列(Food_Categories.food_categories)上进行连接,而不是在一个表(或者说映射的模型对象)上。简单来说,你应该用下面的查询来修正这个错误:

results = Food.query.join(Food_Categories).all()

这样可以解决错误,但生成的 SQL 语句可能不是你想要的,因为即使有连接,它只会返回 Food 的实例。

如果你想构建一个能生成你心中想要的 SQL 语句的查询,可以使用:

results = (db.session.query(Food._id, Food.food_name,
        Food_Categories.food_categories,)
    .join(Food_Categories)).all()
for x in results:
    # print(x)
    print(x._id, x.food_name, x.food_categories)

请注意,在这种情况下,结果不是 Food 的实例,而是包含3个列值的 元组

撰写回答