【问题标题】:Flask-SQLAlchemy - model has no attribute 'foreign_keys'Flask-SQLAlchemy - 模型没有属性'foreign_keys'
【发布时间】:2013-10-12 20:56:27
【问题描述】:

我用 Flask-SQLalchemy 创建了 3 个模型:用户、角色、用户角色

角色.py:

class Role( ActiveRecord, db.Model ):

    __tablename__ = "roles"

    #   Schema
    id = db.Column( db.Integer, primary_key = True )
    name = db.Column( db.String( 24 ), unique = True )
    description = db.Column( db.String( 90 ) )

    users = db.relationship( "User", secondary = "UserRole", \
        backref = db.backref( "roles" ) )

user.py:

class User( db.Model, ActiveRecord ):

    __tablename__ = "users"

    #   Schema
    id = db.Column( db.Integer, primary_key = True )
    email = db.Column( db.String( 90 ), unique = True )
    password = db.Column( db.String( 64 ) )

    #   Relations
    roles = db.relationship( "Role", secondary = "UserRole", \
        backref = db.backref( "users" ) )

user_role.py:

class UserRole( ActiveRecord, db.Model ):

    __tablename__ = "user_roles"

    #   Schema
    user_id = db.Column( db.Integer, db.ForeignKey( 'users.id' ), primary_key = True )
    role_id = db.Column( db.Integer, db.ForeignKey( 'roles.id' ), primary_key = True )

如果我尝试(在控制台中)通过User.query.all() 获取所有用户,我会得到AttributeError: 'NoneType' object has no attribute 'all',如果我再试一次,我会收到另一个错误消息:

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

谁能阐明我到底做错了什么?我想几个月前我的这段代码运行良好,但我最近更新了 SQLAlchemy、Flask 和 Flask-SQLAlchemy,但它停止了。这只是一个附带项目。

【问题讨论】:

  • 发布源代码的部分原因是我们可以尝试重现我们这边的问题。但是,如果我们不知道 ActiveRecord 是什么,或者您如何设置您尝试在其中运行命令的“控制台”,我们就无法做到这一点。有没有办法创建一个复制问题的脚本?

标签: python sqlalchemy flask flask-sqlalchemy


【解决方案1】:

这里有点困难,因为您使用了一些未知的基类,例如“ActiveRecord”等。但是,看起来“次要”参数是错误的:

class User( db.Model, ActiveRecord ):

    __tablename__ = "users"

    #   Schema
    id = db.Column( db.Integer, primary_key = True )
    email = db.Column( db.String( 90 ), unique = True )
    password = db.Column( db.String( 64 ) )

    #   Relations
    roles = db.relationship( "Role", secondary = "UserRole", \
        backref = db.backref( "users" ) )

secondary 需要引用 Table 对象,而不是映射类,如果按字符串名称,那么它将是 "user_roles"

    roles = db.relationship( "Role", secondary = "user_roles", \
        backref = db.backref( "users" ) )

【讨论】:

  • 更好的方法是避免硬编码,所以我更喜欢使用:secondary=lambda: ModelClass.__table__,在这种情况下它将是secondary=lambda: UserRole.__table__
  • @WBAR 为什么需要 lambda 而不是只做secondary=UserRole.__table__?我在没有 lambda 的情况下尝试了它,它似乎工作正常,但我不想在下线时遇到意外。
  • 它必须是可调用的,因为这个变量将在运行时稍后被填充
猜你喜欢
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 2022-11-06
  • 2020-07-08
  • 2019-03-29
  • 1970-01-01
相关资源
最近更新 更多