2017-07-07 42 views
-2

我想在SQLAlchemy python中實現自連接。如何自加入表並選擇SQLAlchemy python中的列?

我有一個表有event_id,event_nameevent_parent_id。我想從DB中爲某些給定的事件ID選擇事件ID,事件名稱和父事件名稱。下面的代碼沒有給出結果。 還有一個疑問,我將如何區分查詢結果中的事件名稱和父名稱。

@app.route("/api/bdi_data_events", methods=["GET"]) 
def get_bdi_data_events(): 
    if request.method == "GET": 
    try: 
     events = request.args.get('events') 
     alias1 = BdiDataLifeCycle 
     alias2 = BdiDataLifeCycle 
     resp = db.session.query(alias1, alias2)\ 
       .join(alias1.event_parent_id, alias2.event_id)\ 
       .filter(alias1.event_id.in_(events.split(',')))\ 
       .values(alias1.event_id, alias1.event_name, alias2.event_name,\ 
       alias1.event_sequence,\ 
       alias1.event_reg_dt, alias1.deleted) 
     d = [] 
     print resp 
     for i in resp: 
      j = {"event_id": i.event_id,"event_name":i.event_name,"event_desc":i.event_desc,"event_name":i.event_name,\ 
       "event_reg_dt": i.event_reg_dt,"deleted": i.deleted\ 
       } 
      d.append(j) 
     return jsonify({"status":"success","response":d}) 
    except Exception, e: 
     print "exception occured-->" 
     print e 
     return raiseError(BAD_REQUEST, {"message":str(e)}) 
    else: 
    return jsonify({"status":"success"}) 

等效MySQL查詢給出正確的結果。

SELECT a.event_id, a.event_name, b.event_name as parent FROM bdi_data_life_cycle a 
left join bdi_data_life_cycle b on 
a.event_parent_id = b.event_id 
where a.event_id in (1,2,3,73,83,95,96,97,98) 


event_id, event_name, parent 
'1', 'data_event', NULL 
'2', 'test_event4455', 'data_event' 
'3', 'test_event5', 'data_event' 
'73', 'test_event10', 'data_event' 
'83', 'test_event7', 'data_event' 
'95', 'test_event101', 'data_event' 
'96', 'test_event100', 'data_event' 
'97', 'test_event120', 'data_event' 
'98', 'test10', 'data_event' 

在這種情況下,事件ID 1是所有剩餘事件的父項。

+1

正確調用'加入()'是'加入(別名2,alias1.event_parent_id == alias2.event_id)',如果你的別名是實際的別名,他們不是。您剛剛將類BdiDataLifeCycle綁定到2個變量/名稱。您應該閱讀或重讀[對象關係教程 - 使用別名](http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#using-aliases)。創建別名的正確方法是'alias1 = aliased(BdiDataLifeCycle)'。 –

+0

你的結果處理似乎也有錯字。在您的字典構造中使用鍵「event_name」兩次,並且結果的字段「i.event_name」在「event_name」中用作值:例如,名稱「event_desc」:例如名稱, - 可能是由於在'values()'中有alias1和2的event_name。 '.label()'後者作爲event_desc。您的密鑰似乎與結果對象中的密鑰相匹配,因此您只需調用['KeyedTuple._asdict()'](http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy。 util.KeyedTuple._asdict)從結果元組中獲取字典。 –

+0

它沒有給出適當的結果。它應該給9行。它給8行。不是'1','data_event',NULL –

回答

0

我已經解決了這個問題,會提供解決方案。我沒有使用適當的別名。我使用了錯誤的連接。我們應該使用label作爲列別名。

@app.route("/api/bdi_data_events", methods=["GET"]) 
def get_bdi_data_events(): 
    if request.method == "GET": 
    try: 
     events = request.args.get('events') 
     alias1 = aliased(BdiDataLifeCycle) 
     alias2 = aliased(BdiDataLifeCycle) 
     resp = db.session.query(alias1, alias2)\ 
       .outerjoin(alias2, alias1.event_parent_id==alias2.event_id)\ 
       .filter(alias1.event_id.in_(events.split(',')))\ 
       .filter(alias2.event_parent_id == None)\ 
       .values(alias1.event_id, alias1.event_name, alias1.event_desc,\ 
       alias1.event_sequence,\ 
       alias1.event_reg_dt, alias1.deleted, alias2.event_name.label("event_parent_name")) 
     d = [] 
     print resp 
     for i in resp: 
      j = {"event_id": i.event_id,"event_name":i.event_name,"event_desc":i.event_desc,"event_sequence":i.event_sequence,\ 
       "event_reg_dt": i.event_reg_dt,"deleted": i.event_parent_name,"event_parent_name": i.event_parent_name\ 
       } 
      d.append(j) 
     return jsonify({"status":"success","response":d}) 
    except Exception, e: 
     print "exception occured-->" 
     print e 
     return raiseError(BAD_REQUEST, {"message":str(e)}) 
    else: 
    return jsonify({"status":"success"})