2017-08-10 7 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を呼び出します。次に、NoSQLテーブルに新しいデータエントリを作成し、SQLテーブル内のjson_dataカラムを返されたURIに更新するPOST APIコールを行います。

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)に移動する作業をしています。私はNoSQLテーブルのデータを更新、挿入、およびソフト削除するためのRESTfulなAPIサーバを実装しました。

私のアプリが他のPythonコードのjson_data列にアクセスしようとするたびにAPIメソッドを自動的に呼び出すSQLAlchemyカスタムタイプを実装したいと思います。

+0

読み取り中に値に沿ってURIを返すことを意味しますか? –

+0

私は、通常の読み取り中に値を求めています。通常の読み込みでは、 'result = SomeTable.query.first()。json_data'のようなものです。私は、 'result.raw_value'のようなものがあるかどうかを尋ねています。そのため、カスタムタイプの背後にURIを取得できます。 –

+1

これを解決する方法はいくつかありますが、プロセスバインドとプロセス結果の両方が書かれているため、「ビルドイン」ソリューションはありません。 1番目 - あなたは "uri = value"の代わりに "self.uri = value"を使用し、 "req = requests.get(uri)"のisteadは "req = requests.get(self.uri)"を使用します。この方法では、uriは "result.uri"によってアクセス可能でなければなりません。 2番目のオプションは、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

私はすべてがうまくいったことを最後に願っています:) –

関連する問題