0

I'm having a problem with SqlAlchemy and a group_by clause. See the SqlAlchemy query below.

I've got a SqlAlchemy query that includes a group_by clause and it's raising an exception, '(cx_Oracle.DatabaseError) ORA-00979: not a GROUP BY expression'. However, when I get the SQL generated by the SqlAlachemy query, and run that manually, the query works fine.

I'm not sure how to figure out what's wrong with the group_by clause. How can I debug this problem and figure out what I can do to fix it?

# create shorthand aliases
b = db.aliased(Batch)
bs = db.aliased(BatchingStatus)
bp = db.aliased(BatchPress)
bst = db.aliased(BatchState)
bit = db.aliased(BatchItem)
bin = db.aliased(BatchInput)
bpri = db.aliased(BatchPriority)
lcu = db.aliased(LCUser)
s = db.aliased(SubBatch)
w = db.aliased(WorkType)
ptw = db.aliased(LCProductToWorkType)
ctp = db.aliased(LCCategoryToProduct)
c = db.aliased(LCCategory)

# for correlated subquery
subq = (
    db.session.query(ctp.product_name)
        .join(c, c.category_id == ctp.category_id)
        .filter(func.lower(c.category_path) == category)
        .filter(ctp.active == 1)
)
# start of problem query
q = db.session.query(
    b.batch_signature.label('batch_signature'),
    b.batch_num,
    b.created_date.label('created_date'),
    bst.code.label('batch_state'),
    func.min(bin.promise_date).label('due_out'),
    bs.job_status,
    bp.press_id.label('press_id'),
    bp.description.label('press_description'),
    bp.code.label('press_code'),
    bp.active.label('press_active'),
    func.listagg(bin.item_id, ',').within_group(bin.item_id).label('subbatches'),
    bs.item_count.label('item_count'),
    bs.product.label('product'),
    bpri.code.label('priority'),
    ptw.display_format.label('product_display_format'),
    c.display_name.label('category_display_name'),
    lcu.coalesce_first_name,
    lcu.coalesce_last_name,
    lcu.coalesce_email,
) \
    .join(bs, (bs.batch_signature == b.batch_signature) & (bs.press_id == b.press_id)) \
    .join(bp, bp.press_id == b.press_id) \
    .join(bst, bst.state_id == b.state_id) \
    .join(bit, bit.batch_id == b.batch_id) \
    .join(bin, bin.batch_input_id == bit.batch_input_id) \
    .join(bpri, bpri.priority_id == bin.priority_id) \
    .join(lcu, lcu.username == bs.actor) \
    .join(s, s.subbatchno == func.to_char(bin.item_id)) \
    .join(w, w.worktypeenum == s.worktypeenum) \
    .join(ptw, ptw.worktypeenum == w.worktypeenum) \
    .join(ctp, ctp.category_to_product_id == ptw.category_to_product_id) \
    .join(c, c.category_id == ctp.category_id) \
    .filter(bs.product.in_(subq)) \
    .filter(b.state_id <= 200) \
    .group_by(
        b.batch_signature,
        b.batch_num,
        b.created_date,
        bst.code,
        bs.job_status,
        bp.press_id,
        bp.description,
        bp.code,
        bp.active,
        bs.item_count,
        bs.product,
        bpri.code,
        ptw.display_format,
        c.display_name,
        lcu.coalesce_first_name,
        lcu.coalesce_last_name,
        lcu.coalesce_email,
    ) \
    .order_by('batch_signature', 'batch_num', 'created_date')
try:
    retval = q.all()
except Exception as e:
    print e

The above doesn't show the models, some of which have @hybrid_property/@.expression methods, like the lcu.coalesce_first_name columns, which are an attempt to hid the @func.coalesce code that I thought was causing the group_by problems.

halfer
  • 19,824
  • 17
  • 99
  • 186
writes_on
  • 1,735
  • 2
  • 22
  • 35

0 Answers0