是否可以将多个数据库中的多个 django 查询集合并到一个查询集中?
Posted
技术标签:
【中文标题】是否可以将多个数据库中的多个 django 查询集合并到一个查询集中?【英文标题】:Is it possible to merge multiple django querysets from multiple databases into one queryset? 【发布时间】:2019-08-17 00:21:15 【问题描述】:我想用 django-rest 创建一个 api 来获取事件。例如:我在多个数据库中有一个表事件。对 /events 的 get 请求应该从所有配置的数据库中读取所有事件,并将所有结果聚合到一个查询集中。然后我想序列化查询集并将json返回给用户。
在 settings.py 中,我创建了一个包含 events 表的数据库列表。 我可以通过一个查询从 DATABASE_1 和 DATABASE_2 查询事件。但是当我尝试在一个循环中聚合结果时,我只能从 DATABASE_2 获取事件。所以聚合不起作用。
如何将这些查询集聚合为一个?或者有没有更好的查询多个数据库的解决方案?
settings.py
DATABASES =
'default': env.db(),
'DATABASE_1': env.db('DATABASE_1'),
'DATABASE_2': env.db('DATABASE_2'),
EVENT_DATABASES = [
'DATABASE_1',
'DATABASE_2',
]
urls.py
urlpatterns = [
path('events/', EventView.as_view())
]
event_view.py
class EventView(APIView):
serializer_class = EventSerializer
def get_queryset(self):
last_24_hours = datetime.datetime.today() - datetime.timedelta(1)
events = Event.objects.none()
for database in settings.EVENT_DATABASES:
events |= Event.objects.using(database).filter(updated_at__gte=last_24_hours).exclude(code='OK')
return events
def get(self, request, format=None):
queryset = self.get_queryset()
serializer = EventSerializer(queryset, many=True)
return Response(serializer.data)
【问题讨论】:
【参考方案1】:你会想要使用itertools.chain
【讨论】:
你有例子吗? 您可以通过以下方式链接查询集:chain(queryset1, queryset2, ... , querysetN) @ChristianBouvier 是的,我可以这样链接它们。问题是序列化程序需要一个查询集对象,但链接后我有一个链对象。我收到错误'itertools.chain' object has no attribute 'model'
。那么有没有办法将其转换回单个查询集?否则链接不是正确的解决方案....【参考方案2】:
如果您尝试合并相同模型的查询集,您可以使用|
运算符。
即
merged_queryset = queryset_1 | queryset_2
否则,您最好的朋友是itertools.chain(如上一个答案所述)。链的结果是一个链对象,您可以通过执行以下操作将其转换为列表:
merged_queryset = list(chain(queryset_1, queryset_2))
希望对您有所帮助!
【讨论】:
以上是关于是否可以将多个数据库中的多个 django 查询集合并到一个查询集中?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Django 中的 get_queryset 方法返回多个查询集对象或添加查询集结果
在 Django 中,正确地制作具有多个类别、多个标签和搜索的查询集?