1. 程式人生 > >用SQLAlchemy建立一對多,多對多關係表

用SQLAlchemy建立一對多,多對多關係表

多對多關係表的建立:

如果建立好多對多關係後,我們就可以通過關係名進行迴圈查詢,比如laowang = Teacher.query.filter(Teacher.name=='laowang').first().classes[0].teachers,

表示查詢老師表中名為老王的所有教的班級中教第一個班級的所有老師物件,複雜吧,不過建立好關係了,這些程式都會自動幫你找到相關資料。

#多對多的關係的表,不是用class建立,而是用db.Table,此處連線的外來鍵都是物件相應的id
association_table = db.Table('teacher_classes',db.metadata,
db.Column(
'teacher_id',db.Integer,db.ForeignKey('teacher.id')), db.Column('classes_id',db.Integer,db.ForeignKey('classes.id')) ) class Teacher(db.Model): __tablename__ = 'teacher' id = db.Column(db.Integer,primary_key=True) tno = db.Column(db.String(10)) name = db.Column(db.String(50)) age
= db.Column(db.Integer) # eacher.query.filter(條件).first()可獲取一個物件 # 建立關係,通過Teacher.query.filter(條件).first().classes即可獲取該老師物件的教的所有班級 # 通過Classes.query.filter(條件).first().teachers即可獲取教該班級物件的所有老師物件資訊 # 引數secondary即是上面建立的多對多關係的表 classes = db.relationship('Classes',secondary=association_table,back_populates='
teachers') def __str__(self): return '{id:%s,tno:%s,name:%s,age:%s}'%(self.id,self.tno,self.name,self.age) def __repr__(self): return self.__str__() class Classes(db.Model): __tablename__ = 'classes' id = db.Column(db.Integer,primary_key=True) cno = db.Column(db.String(10)) name = db.Column(db.String(50)) # 建立關係,通過Teacher.query.filter(條件).first().classes即可獲取該老師物件的教的所有班級資訊 # 通過Classes.query.filter(條件).first().teachers即可獲取教該班級物件的所有老師物件資訊 teachers = db.relationship('Teacher',secondary=association_table,back_populates='classes') def __str__(self): return self.name def __repr__(self): return self.__str__() db.create_all()

完整程式碼:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()
import config

app = Flask(__name__)
app.config.from_object(config)

db = SQLAlchemy(app) #與資料庫建立連線



#多對多的關係的表,不是用class建立,而是用db.Table,此處連線的外來鍵都是物件相應的id
association_table = db.Table('teacher_classes',db.metadata,
db.Column('teacher_id',db.Integer,db.ForeignKey('teacher.id')),
db.Column('classes_id',db.Integer,db.ForeignKey('classes.id'))
)



class Teacher(db.Model):
  __tablename__ = 'teacher'
  id = db.Column(db.Integer,primary_key=True)
  tno = db.Column(db.String(10))
  name = db.Column(db.String(50))
  age = db.Column(db.Integer)
  # eacher.query.filter(條件).first()可獲取一個物件
  # 建立關係,通過Teacher.query.filter(條件).first().classes即可獲取該老師物件的教的所有班級
  # 通過Classes.query.filter(條件).first().teachers即可獲取教該班級物件的所有老師物件資訊
  # 引數secondary即是上面建立的多對多關係的表
  classes = db.relationship('Classes',secondary=association_table,back_populates='teachers')
  def __str__(self):
      return '{id:%s,tno:%s,name:%s,age:%s}'%(self.id,self.tno,self.name,self.age)
  def __repr__(self):
      return self.__str__()



class Classes(db.Model):
  __tablename__ = 'classes'
  id = db.Column(db.Integer,primary_key=True)
  cno = db.Column(db.String(10))
  name = db.Column(db.String(50))
  # 建立關係,通過Teacher.query.filter(條件).first().classes即可獲取該老師物件的教的所有班級資訊
  # 通過Classes.query.filter(條件).first().teachers即可獲取教該班級物件的所有老師物件資訊
  teachers = db.relationship('Teacher',secondary=association_table,back_populates='classes')
  def __str__(self):
      return self.name
  def __repr__(self):
      return self.__str__()





db.create_all()

# 例項化,並操作資料庫
@app.route('/')
def hello_world():
    teacher1 = Teacher(tno=10,name='laowang',age=29)
    teacher2 = Teacher(tno=10, name='laoli', age=29)
    db.session.add(teacher1)
    db.session.add(teacher2)
    
    banji = Classes(cno='6年1班',name='6年1班')
    banji2 = Classes(cno='6年2班', name='6年2班')
    db.session.add(banji)
    db.session.add(banji2)


    
    
    db.session.commit()
    #

    # teacher1 = Teacher.query.filter(Teacher.id == 1).first()
    # 查詢老師表中名為laowang所教的所有班級物件
    laowang = Teacher.query.filter(Teacher.name=='laowang').first()
    laowangClass = laowang.classes
    print(laowang)
    print(laowangClass)
    # 列印教第一個班級所有的老師物件,
    print(laowangClass[0].teachers)



    return 'helloworld'



if __name__ == '__main__':
    app.run()
View Code

此處的config配置:

from datetime import timedelta
DEBUG = True
SECRET_KEY = "123456"
PERMANENT_SESSION_LIFETIME = timedelta(days=7)


HOSTNAME = '127.0.0.1'  # 主機名
PORT = 3306  # 埠號
DATABASE = 'cms'  # 資料庫名稱
USERNAME = 'root'  # 使用者名稱
PASSWORD = '123456'  # 密碼


#資料庫SQLAlchemy,SQLALCHEMY_DATABASE_URI
DB_URI = 'mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8'.format(
    USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI

SQLALCHEMY_TRACK_MODIFICATIONS = False
View Code

 

一對多的關係:

class User(db.Model):
    __tablename__ = 'user' #如果不想將類名作為表名,可以使用這個方式更改表名
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    username = db.Column(db.String(100),nullable=False)

class Article(db.Model):
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    title = db.Column(db.String(100),nullable=False)
    content = db.Column(db.Text,nullable=False)
    # 設定作者ID,user表裡的id,使2表通過anthor_id聯絡在一起
    author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
    # 通過Article.query.filter(條件).author即可查詢到相應文章的作者資訊
    # 通過User.query.filter(條件).articles即可查詢相應的使用者對應的文章
    author = db.relationship('User',backref=db.backref('articles'))

    # author = db.relationship('User',backref=db.backref('articles'))

    #1對1是1對多的一種特殊情況,只需要在最後設定uselist=False,表示限定每個使用者只能寫一篇文章
    # author = db.relationship('User', backref=db.backref('articles'), uselist=False)



db.create_all()