美文网首页
Tornado 数据库_ORM_SQLAlchemy_表关系和简

Tornado 数据库_ORM_SQLAlchemy_表关系和简

作者: Python野路子 | 来源:发表于2018-07-09 22:47 被阅读0次

    在数据库,所谓表关系,只是人为认为的添加上去的表与表之间的关系,只是逻辑上认为的关系,实际上数据库里面的表之间并没有所谓的表关系。

    一对一表关系

    创建Module
    需要先创建对应的 Module ,这里采用之前建立好的 User 和 UserDetails。

    class User(Base):
        __tablename__ = 'users' #数据库中表明
        id = Column(Integer,primary_key=True,autoincrement=True) #Column 用来创建表字段的一个方法
        username = Column(String(12))
        password = Column(String(20))
        creatime = Column(DateTime,default=datetime.now)
        _locked = Column(Boolean,default=False,nullable=False)
    
    class UserDetails(Base):
        __tablename__ = 'user_details'
        id = Column(Integer,primary_key=True,autoincrement=True)
        id_card = Column(Integer,nullable=True,unique=True)
        last_login =Column(DateTime)
        login_num = Column(Integer,default=0)
        user_id = Column(Integer,ForeignKey('users.id'))
    

    relationship

    from sqlalchemy.orm import relationship,backref
    #在UserDetails中添加如下代码
    
        #在使用relationship的时候上面必须要有ForeignKey
        userdetail = relationship('User', backref='details', uselist=False, cascade='all')
    

    使用:

    rows = session.query(User).get(2) #获得id为2的数据信息
    print(rows.username)
    print(rows.details)
    
    rows = session.query(UserDetails).get(2)
    print(rows.userdetail)
    
    自动添加属性

    在刚才这里, User 里面本来是没有 details 这个属性的,但是在 UserDetails 里面添加 relationship 之后,User 实例会自动加上 details 属性。

    relationship

    表关系是逻辑上的关系,但是 mysql 中并没有直接说明表关系的东西,外键约束是一个表现形式,外键是一种表之间的约束,可以用来表示这种关系
    在SQLAlchemy里面,这个relationship代表了一对多的关系,当然我们可以通过参数改变关系,它默认是一对多的关系,而这个关系是SQLAlchemy里面的,和数据库没有关系,但是relationship是和外键一起使用的。

    relationship参数分解
    relationship('User', backref='details', uselist=False, cascade='all')
    

    User: 关联的 Module;
    backref: 在对应的 Module 中添加属性;
    uselist: 表示 一对多 关系, 如果是一对多关系,则不需要重新赋值,如果是一对一关系,则需要赋值为 False;
    cascade: 自动关系处理,就和 MySQL 中的 ON DELETE 类似;

    cascade

    cascade 所有的可选字符串项是:

    all , 所有操作都会自动处理到关联对象上.

    save-update , 关联对象自动添加到会话.

    delete , 关联对象自动从会话中删除.

    delete-orphan , 属性中去掉关联对象, 则会话中会自动删除关联对象.

    merge , session.merge() 时会处理关联对象.

    refresh-expire , session.expire() 时会处理关联对象.

    expunge , session.expunge() 时会处理关联对象.

    正向反向查询

    分辨正向反向查询,主要看ForeignKey在哪个Module.


    image.png

    一对多关系

    relationship默认是一对多关系,uselist=True,默认是True,因此可以省略不写。

    多对多关系

    创建Module

    from sqlalchemy import Table
    
    #中间表
    user_article = Table('user_article',Base.metadata,
                         Column('user_id',Integer,ForeignKey('users.id'),primary_key=True),
                         Column('article_id',Integer,ForeignKey('article.id'),primary_key=True)
                         )
    
    class Article(Base):
        __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)
    
        def __repr__(self):
            return 'Article(id=%s, content=%s, creat_time=%s)' % (
                self.id,
                self.content,
                self.create_time
            )
    

    包管理

    • 包概念:
      把很多模块放到一个文件夹里面,就可以形成一个包。

    • 包管理:
      当把很多模块放在文件中时,为了方便引用包中的模块,引入了包管理。

    • __init__.py:
      在包管理中,加入此模块,则包名可以直接通过属性访问的方式,访问此模块内的对象,此模块不加上可能不会报错,但是规范是要加上,文件内容可以为空。

    • 相对路径导入:
      在包管理中,可以通过 . (一个点) 和 .. (两个点)分别来导入同层和上一层的模块。

    • 引入作用:
      在包中,如果包中模块要导入同一包中的其他模块,就必须使用此方法导入。

    • 使用方法:
      from .module(..module) import obj (as new_name)

    • 引入之后的影响:
      当一个模块中出现此导入方式,则该模块不能被直接运行,只能被导入。


      image.png

    简单的登录

    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    from data.user_module import User
    from tornado.options import define,options
    define('port', default=8080, help='run port', type=int)
    
    
    class LoginHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('login.html')
            
        def post(self,*args,**kwargs):
            user = self.get_argument('name','')
            username = User.by_name(user)
            passwd = self.get_argument('password','')
            print(user,username,passwd)
            if username and passwd == username[0].password:
                self.render('home.html',username=username)
            else:
                self.write('用户名或密码错误')
    
    
    application = tornado.web.Application(
        handlers = [
            (r'/login',LoginHandler),
        ],
    
        template_path = 'templates', #想要Tornado能够正确的找到html文件,需要在 Application 中指定文件的位置
        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()
    

    register.html

    <body>
        <form method="post" action="/register">
            用户名:<input type="text" name="name"/><br/>
            密 码:<input type="password" name="password"/><br/>
            <input type="submit" value="注册" />
        </form>
    </body>
    

    home.html

    <body>
    {% if username %}
    欢迎用户{{username[0].username}}登录
    <br/>
    {% else %}
    你还没有登录
    {% end %}
    </body>
    

    相关文章

      网友评论

          本文标题:Tornado 数据库_ORM_SQLAlchemy_表关系和简

          本文链接:https://www.haomeiwen.com/subject/tlhxpftx.html