Автоматически добавлять контрольную сумму SHA-1 для столбца как другого столбца в таблице SQLAlchemy

1

Я работаю с базой данных SQLAlchemy.

У меня простая схема с столбцами id, data и timestamp. Столбец timestamp автоматически заполняется текущей датой/временем следующим образом:

Column('timestamp', DateTime, nullable=False, default=datetime.now)

Я хочу добавить еще один столбец, содержащий контрольную сумму SHA- 1 столбца data. Что-то вроде:

# notice this is INVALID CODE
Column('checksum', String, nullable=False, unique=True,
       default=hashlib.sha1(this_table.data).hexdigest())

Любые предложения?

Спасибо.

Edit:

Ближайшим я пришел к этому, чтобы управлять "автоматизацией" на уровне объекта (в отличие от уровня таблицы). Я просто определяю столбец checksum как

Column('checksum', String, nullable=False, unique=True)

и измените конструктор объекта, сопоставленного с этой таблицей, как:

def __init__(self, data):
 self.data = data
 self.checksum = hashlib.sha1(self.data).hexdigest()

Он работает так, как ожидалось, но мне все еще интересно, есть ли способ сделать это на уровне "таблицы" (как в timestamp, где я ничего не делаю на уровне объекта, но правильно назначаю текущую дату/времени)

Теги:
sqlalchemy

1 ответ

2
Лучший ответ

SqlAlchemy MapperExtension позволяет создавать боковые триггеры/крючки code- для событий.

http://www.sqlalchemy.org/docs/06/orm/interfaces.html?

В основном вы хотите создать before_insert и before_update, которые выполняют дополнительные действия. У меня есть пример использования этого, чтобы убедиться, что я копирую содержимое из одного столбца в полнотекстовую индексированную таблицу в другом месте в базе данных:

init.py # L269" > https://github.com/mitechie/Bookie/blob/master/bookie/models/ INIT.py # L269

Таким образом, расширение вашего mapper может быть чем-то вроде

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()
    }

Это делает декларативный путь. Вы также можете сделать это с помощью команд ручного сопоставления.

  • 0
    Также отметим, что в SqlAlchemy 0.7 этот рефакторинг превращен в полную базу событий, и вы можете проверить это: sqlalchemy.org/docs/orm/events.html
  • 0
    Очень полезное расширение - большое спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню