tornado 08 数据库-ORM-SQLAlchemy-表关系和简单登录注册

Posted 许铖铖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tornado 08 数据库-ORM-SQLAlchemy-表关系和简单登录注册相关的知识,希望对你有一定的参考价值。

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,UserDetails

rows = 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 Table

user_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类里面写入
    @classmethod
    def by_name(cls,name):
        return  session.query(cls).filter(cls.username==name).all() #通过装饰器来获取类名

 

以上是关于tornado 08 数据库-ORM-SQLAlchemy-表关系和简单登录注册的主要内容,如果未能解决你的问题,请参考以下文章

Python Tornado Websocket 处理程序在接收数据时阻塞

1.Tornado简介&&本专栏搭建tornado项目简介

认识tornado

我想创建一个基于 HTML5 + python (tornado) 的多人游戏:)

2016-08-31

除 Tornado 被制裁外,监管大棒曾经如何挥舞?