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,UserDetailsrows = 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 Tableuser_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類里面寫入 @classmethoddef by_name(cls,name):return session.query(cls).filter(cls.username==name).all() #通過裝飾器來獲取類名
?