一對一表關係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()