我有一些具有不同属性(请求)的classess,它们都应该与另一个类有关(通知)
我的结构是这样的:
db = SQLAlchemy()
class RequestMixin(object):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
description = db.Column(db.Text(250))
@declared_attr
def __tablename__(self):
return self.__name__.lower()
@declared_attr
def notification_id(self):
return db.Column(db.Integer, ForeignKey('notification.id'))
@declared_attr
def notification(self):
return db.relationship('Notification')
def DailyLeaveRequest(db.Model, RequestMixin):
demand_date = db.Column(db.Date, nullable=False)
def HourlyLeaveRequest(db.Model, RequestMixin):
demand_date = db.Column(db.Date, nullable=False)
time_from = db.Column(db.String(10), nullable=False)
time_to = db.Column(db.String(10), nullable=False)
def FundRequest(db.Model, RequestMixin):
amount = db.Column(db.Integer)
class Notification(db.Model):
__tablename__='notification'
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
seen = db.Column(db.BOOLEAN, nullable=False, default=False)
concept = db.Column(db.Integer, nullable=False)
# and some relationships to users which doesn't matter here
通过这种方式,我可以通过每个Request对象访问Notification对象,但由于没有' backref',我无法以相反的方式访问。
所以我现在要做的就是检查Notification.concept并手动查询相关的请求。这样:
if notification_obj.concept == 1:
related_request = DailyLeaveRequest.query.filter_by(notification_id=notification_obj.id).first()
elif notification_obj == 2:
.
.
这很恶心。 (我有超过3个请求类)
当我尝试添加这样的反射时:
.
.
@declared_attr
def notification(self):
return db.relationship('Notification', backref='request')
.
.
,我收到此错误:
sqlalchemy.exc.ArgumentError:创建backref'请求'时出错关系' HourlyLeaveRequest.notification':该名称的属性存在于mapper' Mapper | Notification | notification'
有没有办法让一个与其他不同类相关的类具有反向访问权限?
答案 0 :(得分:1)
你应该看看SQLAlchemy's polymorphic relationships。
使用它的最简单方法是joined table inheritance。它允许您定义包含所有常见属性的基表,包括与Notification
的关系。
class Request(db.Model):
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
description = db.Column(db.Text(250))
notification_id = db.Column(db.Integer, ForeignKey('notification.id'))
notification = db.relationship('Notification')
type = db.Column(db.String(50))
__mapper_args__ = {
'polymorphic_identity': 'request',
'polymorphic_on': type,
}
class DailyLeaveRequest(Request):
id = db.Column(db.Integer, db.ForeignKey('request.id'), primary_key=True)
demand_date = db.Column(db.Date, nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'dailyleave',
}
class HourlyLeaveRequest(Request):
id = db.Column(db.Integer, db.ForeignKey('request.id'), primary_key=True)
demand_date = db.Column(db.Date, nullable=False)
time_from = db.Column(db.String(10), nullable=False)
time_to = db.Column(db.String(10), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'hourlyleave',
}
def FundRequest(Request):
id = db.Column(db.Integer, db.ForeignKey('request.id'), primary_key=True)
amount = db.Column(db.Integer)
__mapper_args__ = {
'polymorphic_identity': 'hourlyleave',
}
然后,您可以查询所有Requests
:
requests = Request.query.all()
for request in requests:
demand_date = getattr(
request, 'demand_date', 'demand_date not available on this type')
print(request.type, demand_date)
Request
的所有属性以及特定的表都可用,但不能用于其他表。
您还可以查询特定类型:
requests = DailyLeaveRequest.query.all():
for request in requests:
print(request.type, request.demand_date)