SQLAlchemy表關係

一對一表關係html

Modulemysql

須要先建立對應的 Module ,這裏採用以前創建好的 User 和 UserDetailsweb

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

自動添加屬性sql

在剛纔這裏, User 裏面原本是沒有 details 這個屬性的,可是在 UserDetails 裏面添加 relationship 以後, User 實例會自動加上 details 屬性數據庫

relationshipsession

表關係是邏輯上的關係,可是 mysql 中並無直接說明表關係的東西,外鍵約束是一個表現形式,外鍵是一種表之間的約束,能夠用來表示這種關係app

在SQLAlchemy裏面,這個relationship表明了一對多的關係,固然咱們能夠經過參數改變關係,它默認是一對多的關係,而這個關係是SQLAlchemy裏面的,和數據庫沒有關係,可是relationship是和外鍵一塊兒使用的。ssh

反向查詢tornado

row = session.query(User).get(4)
print(row)
print(row.details)  #會把對應的詳情表裏面的對應的信息打印出來

結果爲:oop

        <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()
相關文章
相關標籤/搜索