【问题标题】:Create MD5 of column in unique constraint sqlalchemy model在唯一约束 sqlalchemy 模型中创建列的 MD5
【发布时间】:2022-01-22 17:04:05
【问题描述】:

我的模型如下,我希望在具有 md5 哈希的特定列上具有唯一索引,但 func.md5(col2) 不起作用。

class TestClass(db.Model):
    __tablename__ = 'my_table'
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    col1 = db.Column(db.String)
    col2 = db.Column(db.String)
    col3 = db.Column(db.Numeric)
    
    __table_args__ = (
        UniqueConstraint('col1', func.md5(col2), name='my_table_unique_idx')
    )

【问题讨论】:

标签: python postgresql sqlalchemy flask-sqlalchemy


【解决方案1】:

有很多解决方案。 ORM 解决方案如下所示:

from sqlalchemy import *
from sqlalchemy import event
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base


username = 'postgres'
password = 'root'
servername = 'localhost'
databasename = 'database_name'
conn_string = f'postgresql+psycopg2://{username}:{password}@{servername}/{databasename}'

Base = declarative_base()


def add_hash(mapper, connection, table, *args, **kvargs):
    table.col1 = func.md5(table.col2)


class TestClass(Base):
    __tablename__ = 'my_table'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    col1 = Column(String, unique=True, nullable=False)
    col2 = Column(String)
    col3 = Column(Numeric)
    
    def __eq__(self, other):
        return self.col1 == other.col1

if __name__ == '__main__':
    engine = create_engine(conn_string)

    # create table if it doesn't exist
    Base.metadata.create_all(engine)

    # example when inserting record
    event.listen(TestClass, "before_insert", add_hash)
    with sessionmaker(engine)() as session:
        new_record = TestClass(col2='test row2', col3=1.2)
        session.add(new_record)
        session.commit()

第二种解决方案是使用 SQL 创建触发器。

create or replace function fn_insert_md5() returns trigger as $$
begin
    if NEW.col1 is null then
        NEW.col1 := md5(NEW.col2);
    end if;
    return new;
end;
$$ language plpgsql;


create trigger trig_insert_md5
before insert
on my_table
for each row
execute procedure fn_insert_md5();

编辑: 用于添加将检查 col2 哈希值是否与 col1 哈希值相同的约束

col2 = Column(String, CheckConstraint('col1=md5(col2)', name='my_table_unique_idx'))

【讨论】:

  • 嘿@pythonman,感谢您的回答,但我不想将哈希值插入表中,我只想对这些列有唯一的约束。
  • 好的,那么在 col1 上添加唯一且可为空的参数就足够了。 col1 = Column(String, unique=True, nullable=False) 如果您希望该列被索引,您也可以添加参数 index=True。
  • 如果你想约束它将检查 col1 hash value = md5(col2),你可以添加 CheckConstraint。它看起来像这样: col2 = Column(String, CheckConstraint('col1=md5(col2)'))
猜你喜欢
  • 2016-08-22
  • 1970-01-01
  • 2021-04-29
  • 2010-12-06
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多