外键的其他相关内容可以参看本文:https://blog.youkuaiyun.com/LCY133/article/details/107688002
外键:MySQL的外键约束(FOREIGN KEY)是表的一个特殊字段。对于两个具有关联关系的表而言,相关联字段中的主键所在表就是主表(父表),外键所在的表就是从表(子表)。
要点:主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
创建表格:
from sqlalchemy import create_engine, and_, or_
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, DECIMAL, Boolean, Enum, DateTime, TEXT, ForeignKey
from sqlalchemy.orm import sessionmaker
# 连接数据库
# 地址
HOSTNAME = '127.0.0.1'
# 数据库
# 几栋
DATABASE = 'class_database'
# 端口
# 门牌号
PORT = 3306
# 用户名和密码
# 钥匙
USERNAME = 'root'
PASSWORD = 'root'
DB_URL = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
engine = create_engine(DB_URL)
# 都要继承这个函数生成的基类
Base = declarative_base(engine)
- 主表
class User(Base):
__tablename__ = 'user1'
id = Column(Integer,primary_key=True,autoincrement=True)
name = Column(String(50))
def __str__(self):
return 'User(name:{})'.format(self.name)
子表与外键:
class Article(Base):
__tablename__ = 'article1'
id = Column(Integer,primary_key=True,autoincrement=True)
title = Column(String(50))
#content = Column(TEXT,nullable=True)
content = Column(TEXT,nullable=False)
uid = Column(Integer,ForeignKey('user1.id',ondelete='RESTRICT'))
创建与添加数据:
Base.metadata.drop_all()
Base.metadata.create_all()
Session = sessionmaker(bind=engine)
session = Session()
user = User(name='cheney')
session.add(user)
session.commit()
article = Article(title='python',content='xxxx',uid=1)
session.add(article)
session.commit()
此时可以正常创建外键
如果添加主表中没有的id,会报错的,比如:
article = Article(title='python',content='xxxx',uid=2)
session.add(article)
session.commit()
提示错误:
'Cannot add or update a child row: a foreign key constraint fails (`class_database`.`article1`, CONSTRAINT `article1_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user1` (`id`))')
[SQL: INSERT INTO article1 (title, content, uid) VALUES (%(title)s, %(content)s, %(uid)s)]
[parameters: {'title': 'python', 'content': 'xxxx', 'uid': 2}]
- 外键约束:
外键约束通过ondelete进行指定,有以下几项:
1.restrict:父表数据被删除,会阻止删除,默认就是这一项
2.no action: 同restrict
3.cascade:级联删除 删除了父表中的内容,字表中对应的内容也会被删除
4.set null :父表数据被删除,字表数据会被设置为NULL
测试代码:
#外键
class Article(Base):
__tablename__ = 'article1'
id = Column(Integer,primary_key=True,autoincrement=True)
title = Column(String(50))
#content = Column(TEXT,nullable=True)
content = Column(TEXT,nullable=False)
#uid = Column(Integer,ForeignKey('user1.id',ondelete='RESTRICT'))
#uid = Column(Integer,ForeignKey('user1.id',ondelete='CASCADE'))
uid = Column(Integer,ForeignKey('user1.id',ondelete='set null'))
其中 ondelete的参数大小写对程序无影响