Google Code Prettify

2019年9月8日 星期日

Python: ORM (many-to-many)

  1. from flask import Flask
  2. from flask_sqlalchemy import SQLAlchemy
  3. from sqlalchemy import Column, String
  4.  
  5. app = Flask(__name__)
  6. app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:passw0rd@localhost/test?charset=utf8"
  7. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
  8. db = SQLAlchemy(app)
  9.  
  10. program = db.Table('program', db.Model.metadata,
  11. db.Column('year', db.Integer, primary_key=True),
  12. db.Column('teacher_id', db.Integer, db.ForeignKey('teacher.id')),
  13. db.Column('student_id', db.Integer, db.ForeignKey('student.id'))
  14. )
  15.  
  16. class Teacher(db.Model):
  17. id = db.Column(db.Integer, primary_key=True)
  18. name = db.Column(db.String(30))
  19. course = db.Column(db.String(20))
  20. students = db.relationship('Student', secondary=program)
  21.  
  22. class Student(db.Model):
  23. id = db.Column(db.Integer, primary_key=True)
  24. name = db.Column(db.String(30))
  25. grade = db.Column(db.String(10))
  26. teachers = db.relationship('Teacher', secondary=program)
  27.  
  28. teacher1 = Teacher(name='Kent Beck', course='TDD')
  29. teacher2 = Teacher(name='Martin Fowler', course='Design Patterns')
  30. teacher3 = Teacher(name='Brendan Burns', course='Distributed Systems')
  31.  
  32. db.session.add_all([teacher1, teacher2, teacher3])
  33. db.session.commit()
  34.  
  35. student1 = Student(name='Steven', grade='1')
  36. student2 = Student(name='Candice', grade='1')
  37. db.session.add_all([student1, student2])
  38. db.session.commit()
  39.  
  40. statement = program.insert().values(year=2019, teacher_id=teacher1.id, student_id=student1.id)
  41. db.session.execute(statement)
  42. statement = program.insert().values(year=2019, teacher_id=teacher3.id, student_id=student1.id)
  43. db.session.execute(statement)
  44.  
  45. statement = program.insert().values(year=2019, teacher_id=teacher1.id, student_id=student2.id)
  46. db.session.execute(statement)
  47. statement = program.insert().values(year=2019, teacher_id=teacher2.id, student_id=student2.id)
  48. db.session.execute(statement)
  49.  
  50. db.session.commit()
  51.  
  52. print(student1.teachers)
  53. print(student2.teachers)
前一篇「Python: ORM (one-to-many)」說明怎麼用 Flask-SQLAlchemy 建立一對多的關係,這篇說明怎麼建立多對多的關係。

如上程式碼,老師和學生存在著授課的關係,學生可以選擇多個課程,老師也可以有許多學生,program 這個 table 即是記錄學生與老師間的關係。
  • line 20、26: 注意裡面的 secondary 屬性,這兩行除了使用
    relationship 建立起學生對老師的一對多關係、老師對學生的一對多關係,還用這個屬性指出另一個關係。 
  • line 12、37: 前一篇有用到 add 一次加入一個 table,add_all 則是允許一次多個。

2019年9月7日 星期六

Python: ORM (one-to-many)

  1. from flask import Flask
  2. from flask_sqlalchemy import SQLAlchemy
  3. from sqlalchemy import Column, String
  4.  
  5. app = Flask(__name__)
  6. app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:password@localhost/test?charset=utf8"
  7. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
  8. db = SQLAlchemy(app)
  9.  
  10. class Sales(db.Model):
  11. emno = db.Column(db.String(6), primary_key=True)
  12. name = db.Column(db.String(20))
  13. customers = db.relationship('Customer')
  14.  
  15. class Customer(db.Model):
  16. cid = db.Column(db.String(10), primary_key=True)
  17. name = db.Column(db.String(20))
  18. emno = db.Column(db.String(6), db.ForeignKey(Sales.emno))
  19.  
  20. sales1 = Sales(emno='001234')
  21. sales1.name = 'Steven'
  22.  
  23. db.session.add(sales1)
  24.  
  25. c1 = Customer(cid='L222149000')
  26. c1.name = 'Shelley'
  27. c1.emno = '001234'
  28.  
  29. c2 = Customer(cid='A123456789')
  30. c2.name = 'Martin'
  31. c2.emno = '001234'
  32.  
  33. db.session.add(c1)
  34. db.session.add(c2)
  35.  
  36. db.session.commit()
  37.  
  38. print(sales1.customers)

前一篇「Python: ORM using Flask」說明如何用 Flask-SQLAlchemy 連線到資料庫進行查詢,既然是 ORM package,這篇來說明一下怎麼建立關係。

如上的程式碼,有一個 table Sales 儲存業務員的資料,另一個 table Customer 儲存客戶資料,每個客戶會分配一個業務員,所以 Sales 和 Customer 間是一對多的關係。
  • line 13: 這是「一」方指向「多」方的方式,在 relationship 間的屬性名稱可任意取名,和資料庫沒有關係,只是方便程式員辨識。
  • line 18: 在「多」方建立一個 foreign key 指向「一」方的 primary key。
  • line 38: 可以印出如下結果,確認這些類別真的和資料庫的 table 產生實質的連繫。
  • [<customer a123456789>, <customer l222149000>]