Хешируйте столбец в postgres, используя sha-256

У меня есть база данных postrges, таблица содержит коды ключей, которые я создал с помощью функции python. Я хотел бы иметь возможность хэшировать этот столбец таким образом, что каждый раз, когда к нему добавляется ключевой код, ключ хешируется. Как я могу получить postgres для этого? Или что будет лучшим способом для хранения этих кодов. Вот пример столбца, который я хотел бы использовать в моей таблице.

 key_codes | 
-----------+
 L7G4J83K  |        
 J70KG169  |         
 L69E540K  |        
 GL8E9C3J  |         
 6C0LE215  |         
 9G01C8JA  |         
 1G9KC58A  |         

Ответ 1

С помощью триггера установите столбец хеша при вставке и обновлении. Для SHA-256 используйте pgcrypto digest модуля расширения pgcrypto.

Поскольку вы не указали свою версию PostgreSQL, я предполагаю, что вы используете текущий 9.2 в следующих примерах.

Здесь, как вызвать функцию digest sha256:

regress=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION

regress=> SELECT digest('blah', 'sha256');
                               digest                               
--------------------------------------------------------------------
 \x8b7df143d91c716ecfa5fc1730022f6b421b05cedee8fd52b1fc65a96030ad52
(1 row)

Обратите внимание, что функция CREATE EXTENSION должна запускаться как суперпользователь.

Триггер довольно прост. Что-то вроде этого будет, если ваша таблица выглядит так:

CREATE TABLE some_table ( key_codes text, hash bytea );

CREATE OR REPLACE FUNCTION hash_update_tg() RETURNS trigger AS $$
BEGIN
    IF tg_op = 'INSERT' OR tg_op = 'UPDATE' THEN
        NEW.hash = digest(NEW.key_codes, 'sha256');
        RETURN NEW;
    END IF;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER some_table_hash_update 
BEFORE INSERT OR UPDATE ON some_table 
FOR EACH ROW EXECUTE PROCEDURE hash_update_tg();

Применение:

regress=> INSERT INTO some_table(key_codes) VALUES ('fred');
INSERT 0 1
regress=> SELECT * FROM some_table;
 key_codes |                                hash                                
-----------+--------------------------------------------------------------------
 fred      | \xd0cfc2e5319b82cdc71a33873e826c93d7ee11363f8ac91c4fa3a2cfcd2286e5
(1 row)

Вы можете уменьшить накладные расходы на запуск триггера, сделав условие обновления условным. Вместо вышеуказанного CREATE TRIGGER используйте оба из них:

CREATE TRIGGER some_table_hash_insert
BEFORE INSERT ON some_table 
FOR EACH ROW 
EXECUTE PROCEDURE hash_update_tg(); 

CREATE TRIGGER some_table_hash_update 
BEFORE UPDATE ON some_table 
FOR EACH ROW 
WHEN ( NEW.key_codes IS DISTINCT FROM OLD.key_codes ) 
EXECUTE PROCEDURE hash_update_tg();