gpt4 book ai didi

python - 在 NDB 中存储关系值的有效方法

转载 作者:行者123 更新时间:2023-12-01 04:59:00 25 4
gpt4 key购买 nike

我有这个数据模型(我制作了它,所以如果有更好的方法,请告诉我)。基本上我已经Club可以有很多Courses 。现在我想知道所有membersinstructors一个俱乐部的。 membersinstructors存储在Course中型号,和 Club有他们的引用。查看代码..

class Course(ndb.Model):
...
instructor_keys = ndb.KeyProperty(kind="User", repeated=True)
member_keys = ndb.KeyProperty(kind="User", repeated=True)

@property
def instructors(self):
return ndb.get_multi(self.instructor_keys)

@property
def members(self):
return filter(lambda x: x.is_active, ndb.get_multi(self.member_keys))

def add_instructor(self, instructor):
if instructor.key not in self.instructor_keys:
self.instructor_keys.append(instructor.key)
self.put()

def rm_instructor(self, instructor):
if instructor.key in self.instructor_keys:
self.instructor_keys.remove(instructor.key)
self.put()

def add_member(self, member):
if member.key not in self.member_keys:
self.member_keys.append(member.key)
self.put()

def rm_member(self, member):
if member.key in self.member_keys:
self.member_keys.remove(member.key)
self.put()

class Club(ndb.Model):
...
owners_keys = ndb.KeyProperty(kind="User", repeated=True)
course_keys = ndb.KeyProperty(kind="Course", repeated=True)


@property
def members(self):
# TODO: is this correct? efficient?
l_members = []
for courses in self.courses:
l_members = l_members + courses.members
return l_members

@property
def trainers(self):
l_trainers = []
for courses in self.courses:
l_trainers = l_trainers + courses.trainers
return l_trainers

@property
def owners(self):
return ndb.get_multi(self.owners_keys)

@property
def courses(self):
return filter(lambda x: x.is_active, ndb.get_multi(self.course_keys))

def add_owner(self, owner):
if owner.key not in self.owners_keys:
self.owner_keys.append(owner.key)
self.put()

def rm_owner(self, owner):
if owner.key in self.owners_keys:
self.owner_keys.remove(owner.key)
self.put()

def add_course(self, course):
if course.key not in self.courses_keys:
self.course_keys.append(course.key)
self.put()

def rm_course(self, course):
if course.key in self.courses_keys:
self.course_keys.remove(course.key)
self.put()

def membership_type(self, user):
if user.key in self.owners_keys:
return "OWNER"
elif user in self.members:
return "MEMBER"
elif user in self.trainers:
return "TRAINER"
else:
raise Exception("The user %s is not in the club %s" % (user.id, self.id))

现在,@property关于Course对我来说似乎没问题。 (我对吗?)但 Club 中的那个似乎效率很低。每次我必须迭代所有 Courses计算 memberstrainers 。另外,这些方法不会被缓存,而是每次都会计算。所以如果成本非常高的话。

有什么建议吗?我正在考虑instructorsmembers作为键列表也在 Club 中,并在每次我将某人添加到 Course 时更新俱乐部,但不确定它是否正确。

PS:有没有更好的方法来同时执行 filterndb.get_multi上?

最佳答案

我会尝试标准化您的模型,而不是采用非标准化模型:

class CourseInscription(ndb.Model):
member = ndb.KeyProperty(kind='User', required=True)
course = ndb.KeyProperty(kind='Course', required=True)
is_active = ndb.BooleanProperty(default=True)

然后,您可以添加类似的内容

class Course(ndb.Model):
# all the stuff already there

@property
def members(self):
return CourseInscription.query(CourseInscription.course == self.key)

一般来说,我更喜欢只返回查询并让调用者决定直接调用它或添加更多过滤/排序,而不是直接执行ndb.get_multi

我通常做的另一个不错的做法是使用它们的父级来构造关系实体的 id,这样我就可以轻松地使用 get by id 检查是否存在,而不必查询

class CourseInscription(ndb.Model):
# all the other stuff

@staticmethod
def build_id(user_key, course_key):
return '%s/%s' % (user_key.urlsafe(), course_key.urlsafe())

# somewhere I can create an inscription like

CourseInscription(
id=CourseInscription.build_id(user_key, course_key),
user=user_key, course=course_key, is_active=True
).put()

# somewhere else I can check if a User is in a Course by just getting... no queries needed
if ndb.Key(CourseInscription, CourseInscription.build_id(user, course)).get():
# Then the user is in the course!
else:
# then it's not

关于python - 在 NDB 中存储关系值的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26740505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com