Данные из отношения 1:n в Django в плоский файл
Я потратил довольно много времени на поиск в Google, но ни один из выводов, похоже, не подходит под мою ситуацию. Я накапливаю небольшое хранилище данных, где я храню все посты на своих страницах в Facebook и делаю снимки производительности (показы, клики, публикации, комментарии...) каждого поста каждые 20 минут в течение первой недели, чтобы я мог создавать некоторые модели прогнозирования для новых постов в более позднем проекте по этому набору данных. Это означает, что существует связь 1:n между Post и Performance-Snapshot, и каждое сообщение имеет около 500 снимков производительности.
Для начала мне просто нужно создать CSV-API для внешнего инструмента визуализации, поэтому мне нужен плоский формат файла для каждого сообщения в заданном временном диапазоне вместе с его окончательным (то есть последним) снимком производительности в той же строке. И проблема в том, что я не могу найти способ собрать список всех постов и их последний снимок производительности за один раз, как я могу сделать с JOINS в прямом SQL.
Мои несколько упрощенные модели:
class FBPost(models.Model):
post_id = models.CharField(max_length=64, unique=True)
type = models.CharField(max_length=32)
message = models.TextField()
description = models.TextField()
created_time = models.DateTimeField()
permalink_url = models.TextField(blank=True)
class Meta:
get_latest_by = 'created_time'
class FBPostPerformance(models.Model):
post_id = models.ForeignKey(FBPost, to_field='post_id', on_delete=models.CASCADE)
date_time = models.DateTimeField(default=django.utils.timezone.now)
post_impressions = models.BigIntegerField(default=0)
post_consumptions_link_clicks = models.BigIntegerField(default=0)
shares_count = models.BigIntegerField(default=0)
comments_count = models.BigIntegerField(default=0)
class Meta:
get_latest_by = 'date_time'
На самом деле, есть еще две модели, не связанные с моим вопросом, которые присваивают посты разным страницам FB, а эти страницы разным брендам, поэтому не спрашивайте, как выглядит соответственно вложенный SQL JOIN...
В любом случае, цикл в представлении (как предложено в Django, чтобы быстро получить последнее в отношении один-ко-многим и другим), чтобы связать воедино FBPost и его последнее связанное FBPostperformance для формирования плоского файла, является неэффективной работой с головоломками и просто не выглядит питонным.
Мне кажется, что prefetch_related или select_related не могут мне помочь, так как они просто уменьшают нагрузку на БД, но мне все еще приходится перебирать все результаты.
Теперь моей самой большой надеждой было использование.values для непосредственного создания плоской файловой структуры по мере необходимости:
postlist_mtd = FBPost.objects.filter(created_time__gte='2018-02-01') \
.values('post_id',
'fbpostperformance__date_time',
'fbpostperformance__post_impressions',
'fbpostperformance__post_consumptions_link_clicks',
'fbpostperformance__shares_count',
'fbpostperformance__comments_count'
)
Но это, конечно, дает мне все возможности FBPost для каждого FBPost. Как мне ограничить fbpostperformance__ только самой последней? Нет ли в Django ORM способа спасти меня от грубой и уродливой атаки SQL JOIN для этого варианта использования?