【flask】外键以及外键的约束关系

一、外键的定义

(1)我的理解

两个内容表达的不同对象的表存在某种逻辑关系就需要用到外键。“内容表达的不同对象”的意思是指例如两个对象房东和房子,房东的属性假设有id,name等,而房子有属性id,area,price,address等,房子和房东是不相同的对象,但是房东和房子又有逻辑上的联系,即某一间房子属于某一个房东。不可能把所有的房东的信息和房子放在一个表中,因为现实中房东可能有多个房子,这样设计出来的表会很复杂,所以应该把房东和房子各建一个表并且用外键将两者连在一起,而外键的作用正是房东和房子之间的纽带。

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base


DB_URI = "mysql://{username}:{password}@{host}:{port}/{db}".format(
    username=USERNAME, password=PASSWORD, host=HOSTNAME, port=PORT, db=DATEBASE
)

engine = create_engine(DB_URI)
Base = declarative_base(engine)
session = sessionmaker(engine)()

class Landlord(Base):
    __tablename__ = 'landlord'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50), nullable=False)


class House(Base):
    __tablename__ = 'house'
    id = Column(Integer, primary_key=True, autoincrement=True)
    address = Column(String(50), nullable=False)
    llid = Column(Integer, ForeignKey('landlord.id')) # 外键指向房东id

(2)注意事项 

外键所指向的不一定是id也可以是别的属性,但是relationship第一个参数的类型要和对应的外键的数据类型要一致。尤其是索引设置成uuid的时候,更要小心。

二、外键约束

(1)设置原因

当某一个房东被删除的时候,被外键关联的房子发现它没有指向的元素,房子表的数据也会遭到破坏,通常默认情况是抛出异常,SQLAlchemy也给用户提供了其他的选择权利例如:当房东被删除后他名下的所有房子都会被删除,或者是只是把房东删除,房子的归属权设为空,正好对应了下面几种参数类型。在实际开发中通常只是设为逻辑上的空,正如很多的云产品,当你删除了所有账户信息,到了下一次加载还是能加载出来。在逻辑上通常会设置一个属性例如叫“is_delete”如果这个值为True就直接给客户返回空,但是数据还是存在数据库,当“is_delete”这个值被置为False的时候还是可以把数据返回给用户的。对于今天的我们已经不用再对内存斤斤计较的时候,这些保留的数据说不定还是能发挥其潜在的价值。

(2)可以设置的参数种类

  • RESTRICT、NO ACTION:房东数据被删除,会阻止删除。NO ACTION在MySQL中,与RESTR功能一致。
  • CASCADE: 房东的数据被删除,房子的数据也会被删除。
  • SET NULL: 房东数据被删除,房子的数据会设置为空。

三、实现各种情况

(1)先添加元素

landlord1 = Landlord(name='Jonathan')
landlord2 = Landlord(name='Joestar')
session.add(landlord1)
session.add(landlord2)
session.commit()

hous1 = House(address='England ', id=1)# 有错误应该是llid
hous2 = House(address='England ', id=2)# 有错误应该是llid
session.add(hous1)
session.add(hous2)
session.commit()

(2)设置为‘RESTRICT’的情况:

在foreignkey中加上参数ondelete=‘参数值’。

llid = Column(Integer, ForeignKey('landlord.id', ondelete='RESTRICT'))

删除第一条数据后:

我竟然删掉了?查看数据库看见foreignkey没有值,推断关联的时候出现问题应该更正成llid。

hous1 = House(address='England ', llid=1)
hous2 = House(address='England ', llid=2)

结果:报错禁止删除。

(3)设置为‘SET NULL’的情况: 

llid = Column(Integer, ForeignKey('landlord.id', ondelete='SET NULL'))

删除第一条数据:DELETE FROM landlord WHERE id=1; 

结果:显示llid的值被置为空。

(4)设置为‘CASCADE’的情况:

 llid = Column(Integer, ForeignKey('landlord.id', ondelete='CASCADE'))

删除第一条数据:DELETE FROM landlord WHERE id=1; 

结果:两个数据都删除了。

发布了46 篇原创文章 · 获赞 75 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_38875300/article/details/98209752