在SQLAlchemy表中自动添加列的SHA-1校验和作为另一列
我正在使用一个SQLAlchemy数据库。
我的数据库结构很简单,有三个列:id
、data
和timestamp
。其中,timestamp
这一列会自动填入当前的日期和时间,具体做法如下:
Column('timestamp', DateTime, nullable=False, default=datetime.now)
我想再添加一个列,用来存放data
列的SHA-1校验和。大概是这样的:
# notice this is INVALID CODE
Column('checksum', String, nullable=False, unique=True,
default=hashlib.sha1(this_table.data).hexdigest())
有什么建议吗?
谢谢。
编辑:
我目前最接近的做法是把“自动化”放在对象层面(而不是表层面)。我简单地把checksum
列定义为:
Column('checksum', String, nullable=False, unique=True)
并且修改与该表对应的对象的构造函数为:
def __init__(self, data):
self.data = data
self.checksum = hashlib.sha1(self.data).hexdigest()
这样做的效果是符合预期的,但我还是想知道有没有办法在“表”层面上做到这一点(就像timestamp
那样,我在对象层面上不做任何事情,但能正确地赋值当前的日期和时间)。
1 个回答
2
SqlAlchemy 的 MapperExtension 让你可以在代码中为事件创建触发器或钩子。
http://www.sqlalchemy.org/docs/06/orm/interfaces.html?
简单来说,你可能想要创建一些在插入数据之前和更新数据之前执行的操作。这段代码的例子是用来确保我能把一个列的内容复制到数据库中另一个全文本索引的表里:
init.py#L269">https://github.com/mitechie/Bookie/blob/master/bookie/models/init.py#L269
所以你的映射器扩展可能看起来像这样:
class DataSHAExtension(MapperExtension):
def before_insert(self, mapper, connection, instance):
instance.checksum = hashlib.sha1(instance.data).hexdigest()
...
然后把它附加到相关的模型上:
Class Something(Base):
__tablename__ = 'something'
__mapper_args__ = {
'extension': DataSHAExtension()
}
这是一种声明式的方式来做这件事。你也可以用手动的映射命令来实现相同的功能。