tornado 08 数据库-ORM-SQLAlchemy-表关系和简单登录注册
引言
#在数据库,所谓表关系,只是人为认为的添加上去的表与表之间的关系,只是逻辑上认为的关系,实际上数据库里面的表之间并没有所谓的表关系
一、一对一表关系
Module
#需要先创建对应的Module,这里采用之前建立好的User和UserDetails relationship from sqlalchemyorm import relationship #在Userdatails中添加如下代码: userdetail = relationship('User',backref='details',uselist=False,cascade='all')#使用 row = session.query(User).get(1) rows.details
relationship
userdetail = relationship('User',backref = 'details',uselist=False,cascade='all') #在使用relationship的时候上面必须要有ForeignKey #类名 User,表示关联的Module # 在子类中通过relationship里面的backref向父类User加上details这个属性 #uselist=False 代表relationship不再表示一对多关系了,表示一对一的关系了 #cascade表示自动关系处理,就和mysql中的ON DELETE 类似 #cascade所有的可选字符串项:1、all,所有操作都会自动处理到关联对象上;2、save_update,关联对象自动添加到会话;3、delete,关联对象自动从会话中删除;4、delete-orphan,属性中去掉关联对象,则会话中会自动删除关联对象;5、merge,session.merge()是会处理关联对象;6、refresh-expire,session.expire()时会处理关联对象;7、expunge,session.expunge()时会处理关联对象#自动添加属性 #在刚才这里,User里面本来是没有details这个属性的,但是在UserDetails里面添加relationship之后,User实例会自动添加上details属性#relationship #表关系是逻辑关系,但是mysql中并没有直接说明表关系的东西,外键约束是一个表现形式,外键是一种表之间的约束,可以用来表示这种关系 #在SQLAlchemy里面,这个relationship代表了一对多的关系,当然我们可以通过参数改变关系,它默认为是一对多的关系,而这个关系是SQLAlchemy里面的,和数据库并没有什么关系,但是relationship是和外键一起使用的
#在relationship.py中输入一下代码from connect import session from user_modules import User,UserDetailsrows = session.query(User).get(2) #获得id为2的数据信息 print(rows) print(rows.username) print(rows.details)rows = session.query(UserDetails).get(1) print(rows) print(rows.userdetail) #只要确定好一对一的关系,子类的userdetail和父类的details属性都可以得到对应的数据
二、多对多关系
#用户与服务器之间的关系可以看成是一对多的关系,但是用户转载的关系就可以看成是多对多的关系,如何在SQLAlchemy表示多对多的关系呢
#在user_modules.py里面添加,记得要导入Table模块 from sqlalchemy import Tableuser_article = Table('user_article',Base.metadata,Column('user_id',Integer,ForeignKey('user.id'),primary_key=True),Column('article_id',Integer,ForeignKey('article.id'),primary_key=True)) #中间表写法class Article(Base): #文章Module__tablename__ = 'article'id = Column(Integer,primary_key=True,autoincrement=True)content = Column(String(500),nullable=True)create_time = Column(DateTime,default=datetime.now)article_user = relationship('User',backref='article',secondary=user_article)#跟上面的区别在于没有uselist,secondary参数传入中间表def __repr__(self):return 'Article(id=%s,content=%s,create_time=%s)'%(self.id,self.content,self.create_time)
三、包管理
#把Module写好以后,该如何导入呢
#在模块中直接导入: from data.user_modules import User #从data包下面的user_modules.py里面导入User
#这就会涉及到包管理#包的概念 #把很多模块放到一个文件夹里面,就可以形成一个包#包管理 #当把很多模块放在文件夹中的时候,为了方便引用包中的模块,引入包管理__init__.py #在包管理中,加入此模块,则包名可以直接通过属性访问的方式,访问此模块内的对象,此模块不加上可能不会报错,但是规范是要加上,文件内容可以为空#相对路径导入 #在包管理中,可以通过.(一个点)和..(两个点)分别来导入同层和上一层的模块
#相对路径导入#引入作用 #在包中,如果包中模块要导入同一包中的其他模块,就必须使用此方法导入#使用方法 from .module(..module) import obj (as new_name)#引入以后的影响 #当一个模块中出现此导入方式,则该模块不能被直接运行,直接被导入
四、简单的登录
import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define,options import time import util.ui_methods import util.ui_modules from data.user_modules import User #导入module包 define('port',default=8080,help = 'run port',type=int) def haha():return 'this is hahahaah'class LoginHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.render('lesson2.html')def post(self, *args, **kwargs):user = self.get_arguments('name')password = self.get_argument('password','')username =User.by_name(user)if username and password == username[0].password:self.render('login_07.html',username = username)else:self.write('用户名或密码错误')application = tornado.web.Application(handlers=[(r'/login',LoginHandler),],template_path = 'templates',static_path= 'static',autoescape = None,ui_methods=util.ui_methods,ui_modules=util.ui_modules,debug=True)if __name__ == '__main__':tornado.options.parse_command_line()http_server = tornado.httpserver.HTTPServer(application)http_server.listen(options.port)tornado.ioloop.IOLoop.instance().start()
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="css/bootstrap.css"><style>* {margin: 0;padding: 0;}</style> </head> <body>{% if username %}欢迎用户{{ username }}登录<br><img src="{{ static_url('images/1.jpg')}}" width="250" height="250"><br>{% else %}您还没有登录{% end %} </body> </html>
#在user_module.py里面导入 from .connect import Base,session#在User类里面写入 @classmethoddef by_name(cls,name):return session.query(cls).filter(cls.username==name).all() #通过装饰器来获取类名