Sqlalchemy 事件監聽與初始化


sqlalchemy不僅僅能自動創建數據庫,更提供了其他更強大的功能,今天要介紹的就是sqlalchemy中的事件監聽,並將其應用到數據庫的初始化中。

需求:當插入設置password字段時,自動加密

# -*- coding:utf-8 -*-
from sqlalchemy import *
from sqlalchemy import event
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
import hashlib

#這里定義一個password加密混淆
password_prefix = "Ad%cvcsadefr^!deaf"

#定義數據庫的賬號、端口、密碼、數據庫名,使用的連接模塊,這里用的是mysqldb
engine = create_engine(
    'mysql+mysqldb://root:1234567@localhost:3306/tech?charset=utf8',
    echo=False#是否輸出數據庫操作過程,很方便調試
)

#定義一個函數,用來獲取sqlalchemy的session
def bindSQL():
    return scoped_session(sessionmaker(bind=engine))

Base = declarative_base()
Base.__table_args__ = {'mysql_engine':'InnoDB'}#定義數據表使用InnoDB

class User(Base):
    __tablename__ = "user"
    id = Column(Integer, primary_key=True)
    name = Column(String(20), unique=True)
    email = Column(String(32), unique=True)
    password = Column(String(32))
    superuser = Column(Boolean, default=False)

metadata = Base.metadata

#定義一個回調函數用於響應觸發事件
def setPassword(target, value, oldvalue, initiator):
    if value == oldvalue:#如果新設置的值與原有的值相等,那么說明用戶並沒有修改密碼,返回原先的值
        return oldvalue
    #如果新值與舊值不同,說明密碼發生改變,進行加密,加密方法可以根據自己需求改變
    return hashlib.md5("%s%s" % (password_prefix, value)).hexdigest()
#設置事件監聽,event.listen(表單或表單字段, 觸發事件, 回調函數, 是否改變插入值)
event.listen(User.password, "set", setPassword, retval=True)

#為了避免重復插入數據,定義一個get_or_create函數,這個是模仿django的,有興趣的同學可以google下
def get_or_create(session, model, **kwargs):
    if "defaults" in kwargs:
        defaults = kwargs["defaults"]
        del kwargs["defaults"]
    else:
        defaults = {}

    instance = session.query(model).filter_by(**kwargs).first()
    if instance:
        return instance, False
    else:
        kwargs.update(defaults)
        instance = model(**kwargs)
        session.add(instance)
        session.flush()
        session.refresh(instance)
        return instance, True

#定義初始化函數
def initModel():
    metadata.create_all(engine)#創建數據庫
    db = bindSQL()#獲取sqlalchemy的session
    #創建超級管理員,這里為了避免多次運行initModel而發生重復插入的情況,使用了get_or_create方法
    obj, created = get_or_create(
        db,
        User,
        name="administrator",
        defaults={
            "email": "332535694@qq.com",
            "password": "administrator",
            "superuser": True
        }
    )
    db.commit()#記得commit喔,不然數據最后還是沒插入
    db.remove()

if __name__ == "__main__":
    initModel()

直接運行:

python models.py

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM