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 在这一点上有点过时,有利于称为hybrids的不太“神奇”的系统。两者都可以在这里使用,下面是混合的示例:

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

请注意,这与查询没有太大关系。在数据到达行集中时对其进行格式化的想法是一种不同的方法,并且也有一些方法可以实现这一点,但如果您只关心引用“文本”和“作者”的打印语句,将其保留为 python 访问模式可能更方便。

于 2013-10-09T02:53:26.333 回答