SQLAlchemy表关系学习(三)

1.表关系

在MySQL中我们讲了表关系,有一对多,一对一和多对多这几种情况。同样的,我们也可以用SQLAlchemy来表示这种关系。

首先是一对多的情况:

#先查看下表结构,然后去写对应的类
mysql> SHOW CREATE TABLE `department`;
mysql> SHOW CREATE TABLE `student`;

from user import session,Base,User
from datetime import datetime,date
from sqlalchemy.orm import relationship
from sqlalchemy import Column,Integer,String,ForeignKey

class Department(Base):
    __tablename__ = 'department'
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(10),nullable=False)
    code = Column(Integer,nullable=False)

    def __repr__(self):
        return 'Department(id=%s,name=%s,code=%s)'%(self.id,self.name,self.code)

class Student(Base):
    __tablename__='student'
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(10),nullable=False)
    dep_id = Column(Integer,ForeignKey('department.id'),doc='学院id')

    stu_dep_for_key = relationship('Department',backref='students')

    def __repr__(self):
        return 'Student(id=%s,name=%s,dep_id=%s)'%(self.id,self.name,self.dep_id)

      
if __name__=='__main__':      
    print(dir(Department))
    rows = session.query(Department).filter(Department.id=='1').first()
    print(rows.students)
    print(rows)
    rows = session.query(Student).filter(Student.dep_id=='1').all()
    print(rows)

在上面这里,我们通过print(dir(Department))的打印值可以看到,Department的属性中增加了一个students属性,通过print(rows.students),可以看到所有Department.id=='1’的学生,这个和第二个查询的结果是一样的,在这里,我们可以很自由的决定数据是否展现出来。

讲relationship之前,先回顾一下,外键它是一个约束,但是并不是代表了关系,之前所讲的一对多,一对一和多对多关系都是在我们的逻辑上,外键约束不能代表这种关系,注意分清外键是约束,没有代表关系。

而在SQLAlchemy里面,这个relationship代表了一对多的关系,当然我们可以通过参数改变关系,它默认是一对多的关系,而这个关系是SQLAlchemy里面的,和数据库没有关系,但是relationship是和外键一起使用的。

接下来我们看看一对一的关系:

from user import session,Base,User
from datetime import datetime,date
from sqlalchemy.orm import relationship
from sqlalchemy import Column,Integer,String,ForeignKey
from department import Student

class Student_details(Base):
    __tablename__='student_details'
    id = Column(Integer,primary_key=True,autoincrement=True)
    id_card = Column(Integer,nullable=False,unique=True)
    telephone = Column(Integer)
    stu_id = Column(Integer,ForeignKey('student.id'))

    stu_deta_for_key = relationship('Student',backref='details',uselist=False,cascade='all')

    def __repr__(self):
        return 'Student_details(id=%s,id_card=%s,telephone=%s,stu_id=%s)'%(self.id,self.id_card,self.telephone,self.stu_id)

if __name__=='__main__':
    rows = session.query(Student).filter(Student.id==1).first()
    print(rows)
    print(dir(Student))
    print(rows.details)

在这里,我们实现了一对一的关系,使用的是uselist=False这个参数。cascade 是自动关系处理,就和MySQL中的ON DELETE类似,但是有区别,参数选项如下:

cascade 所有的可选字符串项是:

  • all , 所有操作都会自动处理到关联对象上.
  • save-update , 关联对象自动添加到会话.
  • delete , 关联对象自动从会话中删除.
  • delete-orphan , 属性中去掉关联对象, 则会话中会自动删除关联对象.
  • merge , session.merge() 时会处理关联对象.
  • refresh-expire , session.expire() 时会处理关联对象.
  • expunge , session.expunge() 时会处理关联对象.

最后看下多对多的关系:

#在Studen上面添加这张表
stu_course = Table('stu_course',Base.metadata,
   Column('stu_id',Integer,ForeignKey('student.id'),primary_key=True),    Column('course_id',Integer,ForeignKey('course.id'),primary_key=True)
        )
#在Sudent中添加这个关系
cou_select = relationship('Course',backref='students',secondary=stu_course)

#添加课程表的模块
class Course(Base):
    __tablename__='course'
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(20),nullable=False)

    stu_select = relationship('Student',backref='course',secondary=stu_course)

    def __repr__(self):
        return 'Course(id=%s,name=%s)'%(self.id,self.name)
    
if __name__=='__main__':    
    rows = session.query(Student).filter(Student.id==1).first()
    print(rows)
    print(dir(Student))

在多对多的关系中,我需要再建立一张表,使用secondary参数来表示多对多关系。

总结

使用SQLAlchemy同样也能表示表的关系,只是表达的方式有些不一样而已。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值