I'm going from SQLite to Postgresql. This has made one of my queries not work. It's not clear to me why this query is allowed in SQLite, but not in Postgresql. The query in question is below in the find_recent_by_section_id_list()
function.
I've tried rewriting the query in multiple ways, but what is confusing me is that this query worked when I was working with SQLite.
The setup is Flask, SQLAlchemy, Flask-SQLAlchemy and Postgresql.
class SectionStatusModel(db.Model):
__tablename__ = "sectionstatus"
_id = db.Column(db.Integer, primary_key=True)
update_datetime = db.Column(db.DateTime, nullable=False)
status = db.Column(db.Integer, nullable=False, default=0)
section_id = db.Column(db.Integer, db.ForeignKey("sections._id"), nullable=False)
__table_args__ = (
UniqueConstraint("section_id", "update_datetime", name="section_time"),
)
@classmethod
def find_recent_by_section_id_list(
cls, section_id_list: List
) -> List["SectionStatusModel"]:
return (
cls.query.filter(cls.section_id.in_(section_id_list))
.group_by(cls.section_id)
.having(func.max(cls.update_datetime) == cls.update_datetime)
)
I would expect that this query would return the latest section statuses, for each section, however I get the following error:
E sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column "sectionstatus._id" must appear in the GROUP BY clause or be used in an aggregate function
E LINE 1: SELECT sectionstatus._id AS sectionstatus__id, sectionstatus...
E ^
E
E [SQL: SELECT sectionstatus._id AS sectionstatus__id, sectionstatus.update_datetime AS sectionstatus_update_datetime, sectionstatus.status AS sectionstatus_status, sectionstatus.section_id AS sectionstatus_section_id
E FROM sectionstatus
E WHERE sectionstatus.section_id IN (%(section_id_1)s, %(section_id_2)s) GROUP BY sectionstatus.section_id
E HAVING max(sectionstatus.update_datetime) = sectionstatus.update_datetime]
E [parameters: {'section_id_1': 1, 'section_id_2': 2}]
E (Background on this error at: http://sqlalche.me/e/f405)
This is the output from a test suite.