【问题标题】:how to fix multiple foreign keys如何修复多个外键
【发布时间】:2019-09-06 11:25:47
【问题描述】:

我正在设置多个外键,但它显示错误

  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 "外键约束为 格式不正确")')

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    当我运行SHOW ENGINE INNODB STATUS 时,它会在LATEST FOREIGN KEY ERROR 部分下显示此错误:

    在被引用的表中找不到被引用的索引 列显示为表中的第一列或列类型,并且 引用的表与约束不匹配。请注意, 在创建的表中更改了 ENUM 和 SET 的内部存储类型 >= InnoDB-4.1.12,并且旧表中的此类列不能被新表中的此类列引用。

    ENUMSET 的东西我们可以忽略,两者之间的类型定义是准确的,这样就剩下关于索引的问题了。

    如果您将index=True 添加到Users.emailfriendgroup.fg_name 的列定义中,它会提供一个索引,可用于mysql 生成外键并且您的表应该创建。

    但是,我建议您重新考虑您的表的主键。您正在使用自动增量主键字段定义这些表中的每一个,但在复合主键中包含其他字段。你不需要这样做。如果您从主键中删除非自动增量列并在它们上添加唯一约束,那么您的所有问题都会消失。

    此外,通过在主键或唯一约束中包含字段friendgroup.owner_email 意味着每个用户只能拥有一个朋友组。那是你要的吗?同样,owner_emailfg_namebelong 表的主键中意味着只有一个用户可以属于特定用户拥有的任何组。

    如果有帮助,我会将这些模型放在一起。它解决了您的外键问题并使用关系属性而不是跨表复制电子邮件地址和组名等数据。

    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")
    

    【讨论】:

    • 感谢您的建议,但有一件事我想问一下,如果我从表朋友组中删除电子邮件地址和所有者电子邮件的连接并属于,那么我如何查看存在于特定组中的用户列表,因为朋友组是组和所属的来源,用户特别根据组存在,并且在主键和外键的帮助下,它不能重复
    • 这就是关系属性允许你做的,你可以通过friendgroup.owner.email访问朋友组所有者的电子邮件。同样,因为每个belong 实例都有一个group_id,所以您始终可以建立一个关系来为您返回每个组的用户。你需要熟悉docs.sqlalchemy.org/en/13/orm/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    相关资源
    最近更新 更多