python - 如何修复多个外键
问题描述
我正在设置多个外键,但它显示错误
from flask_sqlalchemy import SQLAlchemy
sql= SQLAlchemy(app)
app.secret_key = os.urandom(24)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql:///test'
app.config['SECERET_KEY'] = 'RANDAM'
class Users(sql.Model):
__tablename__='users'
id = sql.Column(sql.Integer, primary_key=True, nullable=False,
default='')
name = sql.Column(sql.String(25),nullable=False, default='')
username = sql.Column(sql.String(25),nullable=False, default='')
email = sql.Column(sql.String(25), primary_key=True,nullable=False,
default='')
password = sql.Column(sql.String(100),nullable=False, default='')
reg_time = sql.func.current_timestamp()
online = sql.Column(sql.String(1),nullable=False, default='')
class friendgroup(sql.Model):
__tablename__='friendgroup'
group_id = sql.Column(sql.Integer,sql.ForeignKey('users.id'),
primary_key=True,nullable=False, default='')
fg_name = sql.Column(sql.String(25), primary_key=True, nullable=False,
default='')
owner_email = sql.Column(sql.String(25),sql.ForeignKey('users.email'),
primary_key=True, nullable=False,default='')
description = sql.Column(sql.String(25), nullable=False, default='')
class belong(sql.Model):
__tablename__ = 'belong'
group_id=sql.Column(sql.Integer,sql.ForeignKey('friendgroup.group_id')
,primary_key=True,nullable=False,default='')
email = sql.Column(sql.String(25),sql.ForeignKey('users.email'),
nullable=False, default='', primary_key=True)
owner_email = sql.Column(sql.String(25),
sql.ForeignKey('friendgroup.owner_email'),nullable=False,
default='', primary_key=True)
fg_name = sql.Column(sql.String(25),
sql.ForeignKey('friendgroup.fg_name'),nullable=False, default='',
primary_key=True)
sql.create_all()
app.run(debug=True)
我希望所有这些都将输入到数据库中,但它显示错误:
sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (1005, 'Can\'t create table
test
.friendgroup
(errno: 150 "Foreign key constraint is wrongly forms")')
解决方案
当我运行时SHOW ENGINE INNODB STATUS
,它在以下部分显示此错误LATEST FOREIGN KEY ERROR
:
在被引用的表中找不到被引用的列作为第一列出现的索引,或者表中的列类型与被引用的表的约束不匹配。请注意,使用创建的表中的 ENUM 和 SET 的内部存储类型发生了变化
>= InnoDB-4.1.12
,并且旧表中的此类列不能被新表中的此类列引用。
我们可以忽略 and 的东西ENUM
,SET
两者之间的类型定义是准确的,这样就剩下关于索引的问题了。
如果您添加index=True
到列定义中Users.email
,friendgroup.fg_name
它提供了一个索引,可用于 mysql 生成外键,并且您的表应该创建。
但是,我建议您重新考虑您的表的主键。您正在使用自动增量主键字段定义这些表中的每一个,但在复合主键中包含其他字段。你不需要这样做。如果您从主键中删除非自动增量列并在它们上添加唯一约束,那么您的所有问题都会消失。
此外,通过friendgroup.owner_email
在主键或唯一约束中包含该字段意味着每个用户只能拥有一个朋友组。那是你要的吗?类似地,在表的主键中包含owner_email
and意味着只有一个用户可以属于特定用户拥有的任何组。fg_name
belong
如果有帮助,这就是我将这些模型放在一起的方式。它解决了您的外键问题并使用关系属性,而不是跨表复制电子邮件地址和组名等数据。
class Users(sql.Model):
__tablename__ = "users"
id = sql.Column(sql.Integer, primary_key=True)
name = sql.Column(sql.String(25), nullable=False)
username = sql.Column(sql.String(25), nullable=False)
email = sql.Column(sql.String(25), unique=True, nullable=False)
password = sql.Column(sql.String(100), nullable=False)
reg_time = sql.Column(
sql.TIMESTAMP, server_default=sql.func.current_timestamp()
)
online = sql.Column(sql.String(1), nullable=False, default="")
class friendgroup(sql.Model):
__tablename__ = "friendgroup"
group_id = sql.Column(
sql.Integer, sql.ForeignKey("users.id"), primary_key=True
)
fg_name = sql.Column(sql.String(25), unique=True, nullable=False)
owner_id = sql.Column(
sql.Integer, sql.ForeignKey("users.id"), nullable=False
)
description = sql.Column(sql.String(25), nullable=False, default="")
owner = sql.relationship("User")
class belong(sql.Model):
__tablename__ = "belong"
group_id = sql.Column(
sql.Integer, sql.ForeignKey("friendgroup.group_id"), primary_key=True
)
user_id = sql.Column(
sql.Integer, sql.ForeignKey("users.id"), primary_key=True
)
user = sql.relationship("User")
group = sql.relationship("friendgroup")
推荐阅读
- python - 以 X 开头并以零或最小数字结尾的 Python XPath
- javascript - 使用 Express 服务器时在我的视图中加载 Webpack 创建的包时出错:“external_”net”:1 Uncaught ReferenceError: net is not defined”
- php - 如何获取 tmp 文件的正确 mimetype
- wget - 如何使用 wget 下载整个动态页面?
- postgresql - 如何为 Ubuntu 18.04 升级到 PostgreSQL 11?
- atom-editor - 如何在 Atom 中使用键盘快捷键关闭选项卡?
- razor - ASP .NET Core 2.1 标识:UserRoles 为空
- java - 如何随机定义开关内的多个变量?
- reactjs - 导入的 JSX 组件 NewsСardMedium 必须在 PascalCase 中——不是吗?
- c++ - FFmpeg -- 使用硬件加速进行视频解码