SQLAlchemy:declared_attr列的外键

时间:2015-06-27 00:49:27

标签: sqlalchemy

我在使用declared_attr列的foreign_keys参数时遇到了问题。我的模型看起来像这样:

class BasicTable(object):
  created = db.Column(db.DateTime)
  last_modified = db.Column(db.DateTime)

  @declared_attr
  def created_by_id(cls):
    return db.Column(db.Integer, db.ForeignKey("app_user.id", use_alter = True, name='fk_created_by_id'))

  @declared_attr
  def created_by(cls):
    return db.relationship("AppUser", foreign_keys='{}.{}'.format(cls.__tablename__, 'created_by_id'))

  @declared_attr
  def last_modified_by_id(cls):
    return db.Column(db.Integer, db.ForeignKey("app_user.id", use_alter = True, name='fk_last_modified_by_id'))

  @declared_attr
  def last_modified_by(cls):
    return db.relationship("AppUser", foreign_keys='{}.{}'.format(cls.__tablename__, 'last_modified_by_id'))

class AppUser(BasicTable, db.Model):
  id = db.Column(db.Integer, primary_key=True)
  email = db.Column(db.String(64))
  service_id = db.Column(db.Integer, db.ForeignKey("service.id"))

因为BasicTable中有两列引用了AppUser,所以我得到的是"模糊的外键"错误,所以我尝试使用如here所述的foreign_keys参数。上面给出了这个错误:

AttributeError: 'Table' object has no attribute 'last_modified_by_id'

当我检查数据库时,该字段确实存在于使用BasicTable的所有表上。是否发生此错误是因为我引用了declared_attr列? This建议如此,但当我尝试使用这样的lambda技术时:

foreign_keys=lambda: cls.created_by_id

我收到此错误:

InvalidRequestError: When initializing mapper Mapper|AppUser|app_user, expression 'BasicTable' failed to locate a name ("name 'BasicTable' is not defined"). If this is a class name, consider adding this relationship() to the <class 'app.models.AppUser'> class after both dependent classes have been defined.

有解决方法吗?谢谢!

1 个答案:

答案 0 :(得分:0)

class BasicTable(object):
  created = db.Column(db.DateTime)
  last_modified = db.Column(db.DateTime)

  @declared_attr
  def created_by_id(cls):
    return db.Column(db.Integer, db.ForeignKey("app_user.id", use_alter = True, name='fk_created_by_id'))

  @declared_attr
  def created_by(cls):
    return db.relationship('AppUser', primaryjoin='%s.created_by_id==AppUser.id' % cls.__name__, 
                           remote_side='AppUser.id')

  @declared_attr
  def last_modified_by_id(cls):
    return db.Column(db.Integer, db.ForeignKey("app_user.id", use_alter = True, name='fk_last_modified_by_id'))

  @declared_attr
  def last_modified_by(cls):
    return db.relationship('AppUser', primaryjoin='%s.last_modified_by_id==AppUser.id' % cls.__name__, 
                           remote_side='AppUser.id')