1

次の SQLAlchemy クラスを定義しています。

Base = sqlalchemy.ext.declarative.declarative_base()
class NSASecrets(Base):
  __tablename__ = 'nsasecrets';
  id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True);
  text = sqlalchemy.Column(sqlalchemy.String);
  author = sqlalchemy.Column(sqlalchemy.String);

今私がやりたいのは、次のようなロジックに応じて「作成者」フィールドをマスクできるようにすることです。

if (allowed):
  nsasecrets = session.query(NSASecrets,**mask=False**);
else:
  nsasecrets = session.query(NSASecrets,**mask=True**);
for nsasecret in nsasecrets:
  print '{0} {1}'.format(author, text);

したがって、この「マスク」パラメーターに応じて、出力が False の場合は「John Smith」になり、出力がマスクされないか、出力がマスクされる場合は「J*** * *h」になります。明らかに、この印刷物でそれを行うことができましたが、問題は印刷物がコードの周りに散らばっており、制御された集中型の方法でこれを行う唯一の方法は、既にマスクされた値を持つ SQLAlchemy オブジェクトを作成することです。それで、これに対するよく知られた解決策はありますか?または、「クエリ」インターフェースをオーバーロードする独自のセッションマネージャーを作成する必要がありますか、それとも他の可能な解決策がありませんか?

ありがとう

4

1 に答える 1

2

これは通常、Python で記述子と呼ばれるものを使用して行うようなものです。記述子を SQLAlchemy でマップされた列と組み合わせる簡単な方法はsynonymを使用することですが、 synonym はこの時点では少し時代遅れであり、ハイブリッドと呼ばれる「魔法」の少ないシステムを支持しています。ここではどちらでも使用できます。以下はハイブリッドの例です。

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, synonym_for
from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()

class NSASecrets(Base):
    __tablename__ = 'nsasecrets'

    id = Column(Integer, primary_key=True)
    _text = Column("text", String)
    _author = Column("author", String)

    def _obfuscate(self, value):
        return "%s%s" % (value[0], ("*" * (len(value) - 2)))

    @hybrid_property
    def text(self):
        return self._obfuscate(self._text)

    @text.setter
    def text(self, value):
        self._text = value

    @text.expression
    def text(cls):
        return cls._text

    @hybrid_property
    def author(self):
        return self._obfuscate(self._author)

    @author.setter
    def author(self, value):
        self._author = value

    @author.expression
    def author(cls):
        return cls._author

n1 = NSASecrets(text='some text', author="some author")

print n1.text
print n1.author

これはクエリとはあまり関係がないことに注意してください。行セットに到着したときにデータをフォーマットするという考え方は別の方法であり、それを実現する方法もいくつかありますが、「テキスト」と「作成者」を参照する print ステートメントだけに関心がある場合は、それを python アクセスパターンとして保持する方が便利でしょう。

于 2013-10-09T02:53:26.333 に答える