zoukankan      html  css  js  c++  java
  • SQLAlchemy表关系

    一对一表关系

    Module

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

    from sqlalchemy.orm import relationship
    ....
    class User(Base):
        .....
    class UserDetails(Base):
        ......
    
        userdetail = relationship('User',backref='details',uselist=False,cascade='all')
        #SQLAlchemy里面用来表示表关系的,一对一
        #relationship只在模型层面上生效,只在模型层面上
        def __repr__(self):           
                ........

    自动添加属性

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

    relationship

    表关系是逻辑上的关系,但是 mysql 中并没有直接说明表关系的东西,外键约束是一个表现形式,外键是一种表之间的约束,可以用来表示这种关系

    在SQLAlchemy里面,这个relationship代表了一对多的关系,当然我们可以通过参数改变关系,它默认是一对多的关系,而这个关系是SQLAlchemy里面的,和数据库没有关系,但是relationship是和外键一起使用的。

    反向查询

    row = session.query(User).get(4)
    print(row)
    print(row.details)  #会把对应的详情表里面的对应的信息打印出来

    结果为:

            <User(id=4,username=小泼,password=55432,create_time=2019-04-01 23:10:56,_locked=False)>
            
    [<UserDetails(id=2,id_card=543,last_login=2019-04-02 23:35:38,login_num=4,user_id=4)>]

    正向查询:

    row= session.query(UserDetails).get(2)
    print(row)
    print(row.userdetail)

    结果为:

    <UserDetails(id=2,id_card=543,last_login=2019-04-02 23:35:38,login_num=4,user_id=4)>
    
            <User(id=4,username=小泼,password=55432,create_time=2019-04-01 23:10:56,_locked=False)>

    使用一对多

    relationship 默认是 一对多 关系

    uselist

    uselist=True

    默认是 True ,因此可以省略不写

    多对多表关系

    用户 和 文章之间,可以是一对多的关系,但是如果用户转载的话,就可以看成是 多对多 关系,那 多对多 关系在 SQLAlchemy 中怎么表示呢?

    在Module中创建中间表

    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)
                         )

    在Module中创建  文章Module

    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
              )

    调用测试:

    row = session.query(User).get(4)
    print(dir(row))
    print(row)
    print(row.article)
    print(row.details)  #会把对应的详情表里面的对应的信息打印出来

    结果展示:

    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 

    '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__mapper__', '__module__',

    '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
    '__subclasshook__', '__table__', '__tablename__', '__weakref__', '_decl_class_registry', '_locked', '_sa_class_manager',

    '_sa_instance_state', 'article', 'create_time', 'details', 'id', 'metadata', 'password', 'username'] <User(id=4,username=小泼,password=55432,create_time=2019-04-01 23:10:56,_locked=False)> [Article(id=1, content=litao进阶了, creat_time=2019-04-05 18:51:34), Article(id=2, content=式微走了, creat_time=2019-04-01 18:52:06)] [<UserDetails(id=2,id_card=543,last_login=2019-04-02 23:35:38,login_num=4,user_id=4)>]

    包跟包管理

    当把 Module 写好之后,该如何调用呢?

    在模块中直接导入:

    from data.user_modules import UserDetails

    执行06-login.py,报错结果如下:

    Traceback (most recent call last):
      File "/home/pyvip/tornado_pro/06-login.py", line 11, in <module>
        from data.user_modules import UserDetails
      File "/home/pyvip/tornado_pro/data/user_modules.py", line 2, in <module>
        from connect import Base
    ImportError: No module named 'connect'

    解决方法:

    简单登录

     定义06-login.py 文件

    import sys
    import tornado.web
    import tornado.ioloop
    import tornado.httpserver
    import tornado.options
    from tornado.web import RequestHandler
    from tornado.options import define,options
    import util.ui_modules
    import util.ui_methods
    # import time
    from data.connect import session
    from data.user_modules import UserDetails, User
    
    define('port',default=8080,help='run server',type=int)
    
    #
    class MainHandler(RequestHandler):
        def get(self):
            self.write('请去login')
    
    
    class LoginHandler(RequestHandler):
        def get(self):
            self.render('in_out.html')
    
        def post(self):
            '''验证逻辑'''
            user = self.get_argument('name',None)
            password = self.get_argument('password',None)
            username = session.query(User).filter(User.username == user).first()print(username)
            if username and  password == username.password:
                self.render('02-templates.html',
                            username = username.username
                            )
            else:
                self.write('登录失败')
    
    
    
    application = tornado.web.Application(
        handlers=[
            (r'/',MainHandler),
            (r'/login',LoginHandler),
        ],
        debug=True,
        template_path = 'templates',
        static_path='static',
        # autoescape = None, #全局取消转义
        ui_methods=util.ui_methods,
        ui_modules=util.ui_modules
    )
    if __name__ == '__main__':
        tornado.options.parse_command_line()
        http_server = tornado.httpserver.HTTPServer(application)
        http_server.listen(options.port)
        tornado.ioloop.IOLoop.current().start()

    渲染模板02-templates.html为

    <!DOCTYPE html>
    {#去掉整个页面的转义#}
    {#{% autoescape None %}#}
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Templates</title>
    </head>
    <body>
    {% if username !='' %}
        欢迎 {{ username }} 登录
    <img src="static/images/01.jpg" width="200px" alt="">
    <img src="{{ static_url('images/02.webp') }}" width="200px" alt="">
    {% else %}
        亲,请登录
    {% end %}
    </body>
    </html>

    登录成功返回如下内容:

    登录失败返回:

    将LoginHandler的post方法的代码简化为get_name方法:

    class LoginHandler(RequestHandler):
        def get(self):
            self.render('in_out.html')
        def post(self):
            '''验证逻辑'''
            user = self.get_argument('name',None)
            password = self.get_argument('password',None)
            # username = session.query(User).filter(User.username == user).first()
            username = User.get_name(user)
            print(username)
            if username and  password == username.password:
                self.render('02-templates.html',
                            username = username.username
                            )
            else:
                self.write('登录失败')

    在user_modules.py文件的User Module下定义get_name方法:

    class User(Base):
      。。。。
        def __repr__(self):
            return '''
            <User(id=%s,username=%s,password=%s,create_time=%s,_locked=%s)>
            '''%(self.id,self.username,self.password,self.create_time,self._locked)
        @classmethod
        def get_name(cls,user):
            '''用来查询用户名的方法'''
            return session.query(cls).filter(cls.username == user).first()
  • 相关阅读:
    微信授权登录
    mpvue 试水的一天
    小程序请求接口统一封装到一个js文件中
    工作中vue项目前后端分离,调用后端本地接口出现跨域问题的完美解决
    百度小程序授权更好体验
    关于智能小程序网络请求封装
    vue 开发webapp 手机返回键 退出问题
    MySQL解决存入数据库和取出数据库时间格式问题
    关于小程序授权更好体验
    关于vue项目中在js中引入图片问题
  • 原文地址:https://www.cnblogs.com/taoge188/p/10660068.html
Copyright © 2011-2022 走看看