【问题标题】:Flask-SqlAlchemy relationship errorFlask-SqlAlchemy 关系错误
【发布时间】:2023-03-16 22:48:01
【问题描述】:

这是我的简单模型

  class Record(db.Model):
      __tablename__ = 'reg_records'
      request_id = db.Column(db.Integer, primary_key = True)
      title = db.Column(NVARCHAR())

  class Field(db.Model):
      __tablename__ = 'reg_fields'
      request_id = db.Column(db.Integer, primary_key= True) 
      name = db.Column(NVARCHAR(), primary_key = True)

现在我想将相关字段映射到记录。我正在遵循 flask-sqlalchemy 规范并得到这个

  class Field(db.Model):
      __tablename__ = 'reg_fields'
      request_id = db.Column(db.Integer, ForeignKey('record.request_id'), primary_key= True) 
      name = db.Column(NVARCHAR(), primary_key = True)

  class Record(db.Model):
      __tablename__ = 'reg_records'
      request_id = db.Column(db.Integer, primary_key = True)
      title = db.Column(NVARCHAR())
      fields = db.relationship(Field, backref = 'record')

但是,当我尝试使用此模型时,出现以下错误

  sqlalchemy.exc.NoForeignKeysError
  NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Record.fields - there are no foreign keys linking these tables.  Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.

primaryjoin 添加到如下关系声明中

    fields = db.relationship(Field, backref = 'record', primaryjoin='Record.request_id==Field.request_id')

没有解决问题,而是给出了新的异常

    sqlalchemy.exc.NoReferencedTableError
    NoReferencedTableError: Foreign key associated with column 'reg_fields.request_id' could not find table 'record' with which to generate a foreign key to target column 'request_id'

如果我用primaryjoin值中的表名替换类名,

    fields = db.relationship(Field, backref = 'record', primaryjoin='reg_records.request_id==reg_fields.request_id')

我又遇到了一个例外

   sqlalchemy.exc.InvalidRequestError
   InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers.  Original exception was: 'Table' object has no attribute 'request_id' 

总的来说,在flask-sqlalchemy中建立一对多关系的正确方法是什么。

【问题讨论】:

    标签: python flask flask-sqlalchemy


    【解决方案1】:

    目前还不是很清楚您要做什么。我假设您正在尝试在记录和字段之间建立一对多的关系(一个记录可以有零个或多个字段)。我还假设您希望每条记录只有一个名为 name 的字段。以下模型根据您的需要设置表和关系:

    from sqlalchemy.schema import UniqueConstraint
    
    class Record(db.Model):
        __tablename__ = 'reg_records'
    
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(NVARCHAR())
    
    
    class Field(db.Model):
        __tablename__ = 'reg_fields'
        __table_args__ = (
            UniqueConstraint('record_id', 'name', name='record_id_name_uix'),
        )
    
        id = db.Column(db.Integer, primary_key=True)
        record_id = db.Column(db.Integer, ForeignKey(Record.id))
        name = db.Column(NVARCHAR())
    
        record = db.relationship(Record, backref='fields')
    

    您现在可以执行创建新记录和字段等操作:

    record = Record(title='a record')
    record.fields.append(Field(name='field1'))
    record.fields.append(Field(name='field2'))
    db.session.add(record)
    db.session.commit()
    

    但是,尝试为同一条记录创建两个同名的字段,当您尝试提交它们时会得到一个 IntegrityError:

    record = Record(title='another record')
    record.fields.append(Field(name='same_name'))
    record.fields.append(Field(name='same_name'))
    db.session.add(record)
    db.session.commit()
    

    最后,请尽量注意 Python 代码的格式,因为它很难阅读。

    【讨论】:

    • 你说得对,我希望Record和Field之间有一对多的关系,所以Record有多个Fields并且名称在一个记录中是唯一的。我将其映射到视图,因此没有真正的主键,这就是 reqest_id 和 name 都设置为 primary_key 的原因。
    • 无论如何,将关系转移到 Field 类就可以了,但是所有示例都以我最初的方式显示它。
    猜你喜欢
    • 1970-01-01
    • 2020-04-15
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 2013-02-11
    • 2017-05-24
    相关资源
    最近更新 更多