Automatically add the SHA-1 checksum of a column as another column in a SQLAlchemy table
I am working with an SQLAlchemy database.
I have a开发者_运维技巧 simple schema with columns id
, data
, and timestamp
. The timestamp
column is automatically populated with the current date/time as follows:
Column('timestamp', DateTime, nullable=False, default=datetime.now)
I want to add another column containing the SHA-1 checksum of the data
column. Something along the lines of:
# notice this is INVALID CODE
Column('checksum', String, nullable=False, unique=True,
default=hashlib.sha1(this_table.data).hexdigest())
Any suggestions?
Thank you.
Edit:
The closest I have come to this is to manage the "automation" at the object level (as opposed to the table level). I simply define the checksum
column as
Column('checksum', String, nullable=False, unique=True)
and modify the constructor of the object mapped to that table as:
def __init__(self, data):
self.data = data
self.checksum = hashlib.sha1(self.data).hexdigest()
It works as expected, but I still wonder if there is a way to do this at the "table" level (as in the timestamp
, where I do nothing at the object level, but correctly assign the current date/time)
The SqlAlchemy MapperExtension allows you to create code-side triggers/hooks for events.
http://www.sqlalchemy.org/docs/06/orm/interfaces.html?
Basically you'd want to create a before_insert and before_update that performs the extra actions. I've got an example using this to help make sure I copy content from one column into a fulltext indexed table elsewhere in the database:
init.py#L269">https://github.com/mitechie/Bookie/blob/master/bookie/models/init.py#L269
So your mapper extension might be something like
class DataSHAExtension(MapperExtension):
def before_insert(self, mapper, connection, instance):
instance.checksum = hashlib.sha1(instance.data).hexdigest()
...
and then attched to the relevent model:
Class Something(Base):
__tablename__ = 'something'
__mapper_args__ = {
'extension': DataSHAExtension()
}
This is doing things the declarative way. You can also do this with the manual mapper commands.
精彩评论