开发者

Automatically add the SHA-1 checksum of a column as another column in a SQLAlchemy table

开发者 https://www.devze.com 2023-03-10 05:26 出处:网络
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 fol

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消