我在对象User
和Groups
之间存在多对多关系。我有一个名为Attends
的关联对象,其中包含额外的字段role
。我想通过使用关联代理来减少关联对象关系的详细程度。不幸的是,当我向组添加新用户时,文档不清楚如何显式添加额外字段role
。
小组课程
class Group(db.Model):
__tablename__ = 'group'
gid = db.Column(db.Integer, primary_key=True, autoincrement=True)
oid = db.Column(db.Integer, db.ForeignKey('organization.oid'), nullable=False)
start_time= db.Column(db.DateTime, nullable=False)
end_time = db.Column(db.DateTime, db.CheckConstraint('end_time > start_time'), nullable=False)
location = db.Column(db.String, nullable=False)
description = db.Column(db.Text)
organization = db.relationship('Organization', back_populates='groups')
#many-to-many db.relationship with users
registered_users = association_proxy('user_groups', 'user')
#one to many db.relationship with tags
tags = db.relationship('Tag', back_populates='group')
def add_user(self, user, role):
if not self.has_user(user):
self.registered_users.append(Attend(user, self, role)) <-- error
else:
raise ValueError('user %s already exists', user)
参加课程
class Attend(db.Model):
__tablename__ = 'attend'
uid = db.Column(db.Integer, db.ForeignKey('user.uid'), primary_key=True)
gid = db.Column(db.Integer, db.ForeignKey('group.gid'), primary_key=True)
user_role = db.Column(db.Enum(*GroupRoles.roles, name='role'))
group = db.relationship('Group',
backref=db.backref('user_groups', cascade='all, delete-orphan'))
user = db.relationship('User')
def __init__(self, user, group, role):
self.user = user
self.group = group
self.user_role = role
执行add_user
方法时收到以下错误:
def _create(self, value):
> return self.creator(value)
E TypeError: __init__() missing 2 required positional arguments: 'group' and 'role'
答案 0 :(得分:1)
user_groups
应该是Attend
个对象的列表(即与Attend
的关系),registered_users
应该是User
个对象的列表。当您追加到registered_users
时,您需要让association_proxy
知道如何在Attend
(docs)中构建相应的user_groups
对象:
registered_users = association_proxy('user_groups', 'user',
creator=lambda u: Attend(user=u, user_role='some_default_role'))
注意:SQLAlchemy不知道role
是什么,因此您需要提供默认值。由于user_groups
关系位于Group
, 知道该群组应该是什么。如果您希望能够add_user(user, role)
,您可以直接直接附加到这段关系:
def add_user(self, user, role):
if not self.has_user(user):
self.user_groups.append(Attend(user=user, user_role=role))
else:
raise ValueError('user %s already exists', user)
请注意,这假设您将Attend
类更改为使用默认构造函数。