【问题标题】:Flask SQLalchemy - AttributeError: foreign_keysFlask SQLalchemy - AttributeError:foreign_keys
【发布时间】:2020-05-05 06:39:44
【问题描述】:

当我尝试在其余 API 上执行我的第一个 GET 请求时,我有这个回溯。目前,数据库中没有存储任何内容。目标是显示一个空答案。

[2020-01-18 18:14:14,501] ERROR in app: Exception on /devices/ [GET]
Traceback (most recent call last):
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/debian/Documents/projects/server-restapi/api/routes/device.py", line 12, in get_list
    devices = Device.query.all()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 512, in __get__
    mapper = orm.class_mapper(type)
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/base.py", line 441, in class_mapper
    mapper = _inspect_mapped_class(class_, configure=configure)
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/base.py", line 420, in _inspect_mapped_class
    mapper._configure_all()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 1337, in _configure_all
    configure_mappers()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 3229, in configure_mappers
    mapper._post_configure_properties()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 1947, in _post_configure_properties
    prop.init()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/interfaces.py", line 196, in init
    self.do_init()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/relationships.py", line 1861, in do_init
    self._setup_join_conditions()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/relationships.py", line 1941, in _setup_join_conditions
    can_be_synced_fn=self._columns_are_mapped,
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/relationships.py", line 2246, in __init__
    self._determine_joins()
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/orm/relationships.py", line 2346, in _determine_joins
    consider_as_foreign_keys=consider_as_foreign_keys,
  File "<string>", line 2, in join_condition
  File "<string>", line 2, in _join_condition
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/util/deprecations.py", line 130, in warned
    return fn(*args, **kwargs)
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/sql/selectable.py", line 918, in _join_condition
    a, a_subset, b, consider_as_foreign_keys
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/sql/selectable.py", line 972, in _joincond_scan_left_right
    b.foreign_keys, key=lambda fk: fk.parent._creation_order
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 949, in __getattr__
    return self._fallback_getattr(key)
  File "/home/debian/Documents/projects/server-restapi/env/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 923, in _fallback_getattr
    raise AttributeError(key)
AttributeError: foreign_keys
127.0.0.1 - - [18/Jan/2020 18:14:14] "GET /devices/ HTTP/1.1" 500 -

引用的模型是:


tags = db.Table('tag_device',
                db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True),
                db.Column('device_id', db.Integer, db.ForeignKey('device.id'), primary_key=True)
                )


class Device(db.Model):
    __tablename__ = 'device'
    id = db.Column(db.String(36), primary_key=True, autoincrement=False)
    entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'), nullable=False)
    location_id = db.Column(db.Integer, db.ForeignKey('location.id'), nullable=False)
    deviceGroup_id = db.Column(db.Integer, db.ForeignKey('deviceGroup.id'), nullable=False)
    name = db.Column(db.String(50))
    layout_id = db.Column(db.Integer, db.ForeignKey('layout.id'), nullable=False)
    configuration = db.Column(db.Text)
    tags = db.relationship('Tag', secondary=tags, lazy='subquery', backref=db.backref('devices', lazy=True))
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    version = db.Column(db.SmallInteger, default=0)

    def __repr__(self):
        return '<Device %r>' % self.name


class Entity(db.Model):
    __tablename__ = 'entity'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    devices = db.relationship('Device', backref='entity', lazy=True)
    deviceGroups = db.relationship('DeviceGroup', backref='entity', lazy=True)
    medias = db.relationship('Media', backref='entity', lazy=True)
    playlists = db.relationship('Playlist', backref='entity', lazy=True)
    tags = db.relationship('Tag', backref='entity', lazy=True)
    tagTypes = db.relationship('TagType', backref='entity', lazy=True)

    def __repr__(self):
        return '<Entity %r>' % self.name


class Location(db.Model):
    __tablename__ = 'location'
    id = db.Column(db.Integer, primary_key=True)
    continent = db.Column(db.String(4), nullable=True)
    country = db.Column(db.String(4), nullable=True)
    state = db.Column(db.String(40), nullable=True)
    address = db.Column(db.String(255), nullable=True)
    city = db.Column(db.String(255), nullable=True)
    zipcode = db.Column(db.String(255), nullable=True)
    name = db.Column(db.String(255), nullable=True)
    devices = db.relationship('Device', backref='location', lazy=True)

    def __repr__(self):
        return '<Location %r>' % self.name


class DeviceGroup(db.Model):
    __tablename__ = 'deviceGroup'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'), nullable=False)
    tags = db.relationship('Tag', secondary=tags, lazy='subquery', backref=db.backref('deviceGroups', lazy=True))
    devices = db.relationship('Device', backref='device_group', lazy=True)
    children = db.relationship('DeviceGroup')
    parent_id = db.Column(db.Integer, db.ForeignKey('deviceGroup.id'))

    def __repr__(self):
        return '<DeviceGroup %r>' % self.name


class Layout(db.Model):
    __tablename__ = 'layout'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), nullable=False)
    path = db.Column(db.String(255), nullable=False)
    devices = db.relationship('Device', backref='layout', lazy=True)

    def __repr__(self):
        return '<Layout %r>' % self.name


class TagType(db.Model):
    __tablename__ = 'tagType'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))
    entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'), nullable=False)
    tags = db.relationship('Tag', backref='tagType', lazy=True)


class Tag(db.Model):
    __tablename__ = 'tag'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))
    entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'), nullable=False)
    tagType_id = db.Column(db.Integer, db.ForeignKey('tagType.id'), nullable=False)

对于一对多、多对多的关系我使用了官方文档https://flask-sqlalchemy.palletsprojects.com/en/2.x/models/

你能帮我理解这个错误吗?

R

【问题讨论】:

  • 在您的DeviceGroup.children 关系中添加backref 时是否会得到不同的结果?我从未处理过此错误,但它可能表明 SQLAlchemy 无法确定模型之间的映射/连接条件。
  • 首先,感谢@djnz 对我的帮助。我已经为此页面stackoverflow.com/questions/20830147/… 尝试了这两种方法。不幸的是,这个配置我仍然有同样的错误:``` children = db.relationship('DeviceGroup', backref=db.backref('parent', remote_side='DeviceGroup.id')) parent_id = db.Column( db.Integer, db.ForeignKey('deviceGroup.id'), index=True) ```
  • 请:在考虑向谷歌发布任何错误消息或您的问题/问题/目标的许多清晰、简洁和准确的措辞之前,无论是否包含您的特定字符串/名称和站点:stackoverflow.com 和标签,并阅读许多答案。在代码问题中给出minimal reproducible example--cut & paste & runnable code;具有期望和实际输出(包括逐字错误消息)的示例输入(作为代码);标签和版本;明确的规范和解释。对于包含最少代码的错误,您可以给出的代码是您显示的代码可以通过您显示的代码扩展为不正常。这里强调“最小”。

标签: python flask sqlalchemy foreign-keys


【解决方案1】:

感谢@djnz领导,我注释了对象之间的所有关系并一一取消注释。多对多关系之一是没有使用好的连接表。

感谢您的帮助, 回复

【讨论】:

    猜你喜欢
    • 2015-03-25
    • 2014-04-12
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    相关资源
    最近更新 更多