外键及其四种约束

外键及其四种约束

  • 外键

    在Mysql中,外键可以让表之间的关系更加紧密。而SQLAlchemy同样也支持外键。通过ForeignKey类来实现,并且可以指定表的外键约束

    class Article(Base):
        __tablename__ = 'article'
        id = Column(Integer,primary_key=True,autoincrement=True)
        title = Column(String(50),nullable=False)
        content = Column(Text,nullable=False)
        uid = Column(Integer,ForeignKey('user.id'))
        def __repr__(self):
            return "<Article(title:%s)>" % self.title
    class User(Base):
        __tablename__ = 'user'
        id = Column(Integer,primary_key=True,autoincrement=True)
        username = Column(String(50),nullable=False)
    

    外键约束有以下几项:

    • 1、RESTRICT:父表数据被删除,会阻止删除。默认就是这一项。
    • 2、NO ACTION:在MySQL中,同RESTRICT。
    • 3、CASCADE:级联删除。
    • 4、SET NULL:父表数据被删除,子表数据会设置为NULL。
  • 表关系:

    表之间的关系存在三种:一对一、一对多、多对多。而SQLAlchemy中的ORM也可以模拟这三种关系。因为一对一其实在SQLAlchemy中底层是通过一对多的方式模拟的

    • 一对多

      拿之前的User表为例,假如现在要添加一个功能,要保存用户的邮箱帐号,并且邮箱帐号可以有多个,这时候就必须创建一个新的表,用来存储用户的邮箱,然后通过user.id来作为外键进行引用

      from sqlalchemy import ForeignKey
      from sqlalchemy.orm import relationship
      class Address(Base):
          __tablename__ = 'address'
          id = Column(Integer,primary_key=True)
          email_address = Column(String,nullable=False)
          user_id = Column(Integer,ForeignKey('users.id'))
          user = relationship('User',backref="addresses")
          def __repr__(self):
              return "<Address(email_address='%s')>" % self.email_address
      
      class User(Base):
          __tablename__ = 'users'
          id = Column(Integer,primary_key=True)
          name = Column(String(50))
          fullname = Column(String(50))
          password = Column(String(100))
          addresses = relationship("Address",backref="user")
      
    • 一对一

      一对一其实就是一对多的特殊情况,从以上的一对多例子中不难发现,一对应的是User表,而多对应的是Address,也就是说一个User对象有多个Address。因此要将一对多转换成一对一,只要设置一个User对象对应一个Address对象即可

      class User(Base):
          __tablename__ = 'users'
          id = Column(Integer,primary_key=True)
          name = Column(String(50))
          fullname = Column(String(50))
          password = Column(String(100))
      
          addresses = relationship("Address",backref='addresses',uselist=False)
          
      class Address(Base):
          __tablename__ = 'addresses'
          id = Column(Integer,primary_key=True)
          email_address = Column(String(50))
          user_id = Column(Integer,ForeignKey('users.id')
          user = relationship('Address',backref='user')
      

      从以上例子可以看到,只要在User表中的addresses字段上添加uselist=False就可以达到一对一的效果

    • 多对多

      多对多需要一个中间表来作为连接,同理在sqlalchemy中的orm也需要一个中间表。假如现在有一个Teacher和一个Classes表,即老师和班级,一个老师可以教多个班级,一个班级有多个老师,是一种典型的多对多的关系,那么通过sqlalchemy的ORM的实现方式

      association_table = Table(
          'teacher_classes',
          Base.metadata,
        	Column('teacher_id',Integer,ForeignKey('teacher.id')),
        	Column('classes_id',Integer,ForeignKey('classes.id'))
        )
      
      class Teacher(Base):
          __tablename__ = 'teacher'
          id = Column(Integer,primary_key=True)
          tno = Column(String(10))
          name = Column(String(50))
          age = Column(Integer)
          classes = relationship('Classes',secondary=association_table,backref='teachers')
      
       class Classes(Base):
          __tablename__ = 'classes'
          id = Column(Integer,primary_key=True)
          cno = Column(String(10))
          name = Column(String(50))
          teachers = relationship('Teacher',secondary=association_table,backref='classes')
      

      要创建一个多对多的关系表,首先需要一个中间表,通过Table来创建一个中间表。上例中第一个参数teacher_classes代表的是中间表的表名,第二个参数是Base的元类,第三个和第四个参数就是要连接的两个表,其中Column第一个参数是表示的是连接表的外键名,第二个参数表示这个外键的类型,第三个参数表示要外键的表名和字段。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值