web.py开发web 第四章 Sqlalchemy(事件监听与初始化)

    上一章讲了sqlalchemy的数据库建立,我想你们应该会慢慢喜欢上用这种方式来建立数据库吧,sqlalchemy不单单能自动建立数据库,更提供了其余更强大的功能,今天要介绍的就是sqlalchemy中的事件监听,并将其应用到数据库的初始化中。 python

    上一章的数据库建立,除了将user表建立出来,咱们并无进行其余的操做,而每每咱们的web开发,总须要在网站中设计一个超级管理员,这个超级管理员不是注册出来的,而是在数据库建立初期就有的,那么,咱们能够在models.py中建立user表,并同时向user表插入超级管理员的信息,而在插入超级管理员或者之后的修改密码、新增用户的时候,咱们的密码都是须要加密的,那么这时就能够添加一个事件触发,当插入设置password字段时,自动加密,好,需求有了,接下来就是行动了,咱们把原来的models.py修改为如下代码:
models.py mysql

# -*- 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()
     将上一章建立的user表删除,运行下python models.py,看看是否是建立user表后插入了超级管理员的数据,并对密码进行加密了:)
相关文章
相关标签/搜索