2017-08-10 49 views
0

我的問題簡而言之:是否可以在SQLAlchemy中訪問自定義類型的原始值?如何獲取SQLAlchemy自定義類型的原始值?

我實現了自定義類型:

class JSONDocument(TypeDecorator): 
    # override field 
    impl = JSON 

    # Write 
    def process_bind_param(self, value, dialect): 
     if value is not None: 
      req = requests.post(url, data=json.dumps({'data': value})) 
      uri = req.json()['uri'] 
      value = uri 
     return value 

    # Read 
    def process_result_value(self, value, dialect): 
     if value is not None: 
      uri = value 
      req = requests.get(uri) 
      value = req.json()['data'] 
     return value 

我的表模型:

class SomeTable(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    # The column with large json data 
    json_data = db.Column(JSONDocument) 

每當我嘗試更新或插入行,這將寫入json_data列作爲一個結果, SQLAlchemy將調用JSONDocumentprocess_bind_param。然後它會執行一個POST API調用,在我的NoSQL表中創建一個新的數據條目,並將我的SQL表中的json_data列更新爲返回的URI。

每當我嘗試訪問json_data列時,它都會對存儲在我的SQL表中的URI執行GET API調用,並返回存儲在我的NoSQL表中的實際JSON數據。

我的問題:如何獲取存儲在JSONDocument所涵蓋的SQL表中的URI?我想在更新json_data時對舊的URI執行DELETE API調用。

我試過使用SQLAlchemy的映射事件回調,但我仍然無法獲得我的自定義類型後面的URI。

請讓我知道,如果我不問清楚我的問題。任何建議或想法表示讚賞。

摘要任務的我試圖做的事:

我有一個PostgreSQL數據庫(RDS)表中的列:id(INT),json_data(串),other_columns ...

由於json_data列佔用太多存儲空間,因此我正在將該列中的數據移動到其他NoSQL數據庫(DynamoDB)。我實現了一個RESTful API服務器,用於更新,插入和軟刪除NoSQL表中的數據。

我想實現一個SQLAlchemy自定義類型,當我的應用程序試圖訪問其他Python代碼中的json_data列時,它將自動調用我的API方法。

+0

您的意思是在讀取過程中將uri沿着值返回嗎? –

+0

不完全,我只想要在正常閱讀期間的價值。通過定期閱讀,我的意思是像'result = SomeTable.query.first()。json_data'。我問是否有像'result.raw_value'這樣的東西,這樣我就可以獲得自定義類型的URI。 –

+1

如何解決這個問題有很多種方法,但沒有「內置」解決方案,因爲進程綁定和處理結果都是由您編寫的。第一 - 你可以使用「self.uri = value」而不是「uri = value」來代替「req = requests.get(uri)」use「req = requests.get(self.uri)」。這樣uri應該可以通過「result.uri」訪問。第二個選項是通過session.execute()使用普通SQL。或者甚至你可以創建另一個類,再次從JSONDocument繼承,然後再次覆蓋process_result_value :) –

回答

1

你有沒有關於擺脫自定義TypeDecorator並將你的邏輯移動到SomeTable類似於這個使用屬性?

class SomeTable(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    # The column with large json data 
    _uri = db.Column(db.JSON) 

    @property 
    def json_data(self): 
     if self._uri is not None: 
      req = requests.get(self._uri) 
      return req.json()['data'] 
     else: 
      return None 

    @json_data.setter 
    def json_data(self, value): 
     req = requests.post(url, data=json.dumps({'data': value})) 
     self._uri = req.json()['uri'] 

    @property 
    def uri(self): 
     return self._uri 
+0

哇。它使用屬性效果非常好!令人驚訝的是,我們用來讀寫屬性和列的代碼完全相同(如果這不是真的,請告訴我)。我將不得不做一些單元測試,以確保一切正常。非常感謝你的建議! :) –

+0

我希望一切順利結束:) –

相關問題