Flask SQLAlchemy query with order_by returns error no such column

本小妞迷上赌 提交于 2021-02-05 12:09:50

问题


Here is my models:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy


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


class Person(db.Model):
    __tablename__ = 'persons'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), nullable=False, unique=True)
    pets = db.relationship('Pet', backref='owner', lazy='dynamic')

    def __init__(self, *args, **kwargs):
        super(Person, self).__init__(*args, **kwargs)

    def __repr__(self):
        return f'<Person id:{self.id} name:{self.name}>'

class Pet(db.Model):
    __tablename__ = 'pets'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), nullable=False, unique=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('persons.id'), nullable=False)

    def __init__(self, *args, **kwargs):
        super(Pet, self).__init__(*args, **kwargs)

    def __repr__(self):
        return f'<Pet id:{self.id} name:{self.name} owner_id:{self.owner_id}>'

I`m trying to get persons list ordered by count of pets with this query:

persons = Person.query.order_by(Person.pets).all()

And getting this error:

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: pets.owner_id
[SQL: SELECT persons.id AS persons_id, persons.name AS persons_name
FROM persons ORDER BY persons.id = pets.owner_id]

What I`m doing wrong? I have a suggestion that I need to make a request with join(), but research in google did not give working solutions.


回答1:


If you inspect the SQL, you'll note that there is no FROM item pets, and so ORDER BY persons.id = pets.owner_id fails. This happens because the relationship attribute Person.pets renders as its ON clause in query context, or in other words as persons.id = pets.owner_id. There are many ways to form the proper query, for example using a JOIN and GROUP BY:

Person.query.\
    outerjoin(Person.pets).\
    group_by(Person.id).\
    order_by(func.count(Pet.id)).\
    all()

The LEFT OUTER JOIN ensures that persons without pets are considered as well.



来源:https://stackoverflow.com/questions/60289173/flask-sqlalchemy-query-with-order-by-returns-error-no-such-column

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!