關於SQLALCHEMY之(一)

SQLALCHEMY是一個不可靠的方案。對於初級開發者而言,並不如SQL語句來得簡明。sql

或者說,我不知道是否是全部的ORM數據庫對象映射方案都存在這麼一種狀況。純以開發邏輯而言。下述兩段代碼的結論是一致的:數據庫

CODE1 : 正確實現session

  partner_name = request.args.get( "partner_name")
  site_name = request.args.get( "site_name")
  delegation_query = db.session.query(Delegation)
  delegation_query = delegation_query.\
    filter(or_(
      Delegation.grantee_id == partner_id,
      Delegation.grantor_id == partner_id))
  if site_name is not None:
    delegation_query = delegation_query.\
      join(Site, Site.id == Delegation.site_id).\
      filter(Site.name.like( '%' + site_name + '%'))
  if partner_name is not None:
    q1 = delegation_query.\
      join(Partner, Partner.id == Delegation.grantee_id).\
      filter(Partner.name.like( '%' + partner_name + '%'))
    q2 = delegation_query.\
      join(Partner, Partner.id == Delegation.grantor_id).\
      filter(Partner.name.like( '%' + partner_name + '%'))
    delegation_query = q1.union(q2)

CODE2 : 錯誤實現學習

  delegation_query = db.session.query(Delegation)
  if partner_name is not None:
    q1 = delegation_query.\
      join(Partner, Partner.id == Delegation.grantee_id).\
      filter(Partner.name.like( '%' + partner_name + '%'))
    q2 = delegation_query.\
      join(Partner, Partner.id == Delegation.grantor_id).\
      filter(Partner.name.like( '%' + partner_name + '%'))
    delegation_query = q1.union(q2)
  if site_name is not None:
    delegation_query = delegation_query.\
      join(Site, Site.id == Delegation.site_id).\
      filter(Site.name.like( '%' + site_name + '%'))
  delegation_query = delegation_query.\
    filter(or_(
      Delegation.grantee_id == partner_id,
      Delegation.grantor_id == partner_id))

 

另外附上這段代碼的實現目標。partner爲用戶。site爲資源。delegation爲用戶對資源的映射關係。spa

即:partner表保存用戶的信息。site表保存資源信息。delegation表以ID爲映射字段保存資源和用戶的對應關係。設計

此處,delegation的做用是,一個用戶將本身擁有的資源的權限部分開放給其餘用戶。對象

 

從系統使用者的角度考慮,輸入的參數爲:用戶名稱,資源名稱。另一個默認的參數是從登陸狀態中取得的,當前用戶的ID。(查詢權限控制)資源

因爲實現模糊匹配的須要。這塊的判斷邏輯以下:開發

  1.  當資源名稱輸入不爲空,須要將關係表和資源表進行鏈接,實現經過名稱查詢資源。文檔

  2.  當用戶名稱輸入不爲空,須要將關係表和用戶表進行鏈接,實現經過名稱查詢資源。

  3.  爲了執行條件2.須要確認關係表和用戶表以哪一個鍵進行鏈接。(因爲受權的關係,關係表中有兩列外鍵對應用戶表ID。一個是資源全部者,一個是受權的目標用戶)

  4.  爲了執行條件3.因爲部分數據庫彷佛不支持FULL JOIN。所以採用UNION進行聯合查詢。

  5.  查詢除了上述1-4條件的基本邏輯外,必須知足這個條件:用戶或者是具備了使用該資源的權限,或者是該資源的全部者。

 

從賦值角度考慮,以及過往的使用方法來看。SQLALCHEMY是支持串行操做的。可是CODE1和CODE2生成的SQL語句是不一樣的。

實際中,CODE2實現的功能,已知在資源名稱和用戶名稱都有輸入值的狀況下,忽略了資源名稱條件,查詢告終果。且未知的狀況是,是否知足了條件5的設計。

 

這件事情來看,不論結果是不是我自身代碼寫法風格的問題。至少這樣來看。並非簡單的串聯問題。

所以對當前階段是否應該使用SQLALCHEMY產生了懷疑。至少若是使用ORM類初期,對於ORM封裝內部的邏輯不瞭解的狀況下,這件事情是不可靠的。

也許有文檔說明這個問題,也許沒有。不過至少上述這麼一點問題是須要關注的,除此之外,對於ORM編寫的SQL的調優,難度會更高。

總不能每次都用print(str(sql))的方式來解決問題吧。雖然這就是學習方法。。。

相關文章
相關標籤/搜索