-
Notifications
You must be signed in to change notification settings - Fork 53
Open
Description
With the following model:
class UserInfoCTEQuerySet(CTEQuerySet):
"""QuerySet attached to the UserInfo.with_rank manager."""
def with_rank(self):
"""Use a Common Table Expression to add rank to UserInfos.
The resulting query looks like:
WITH cte AS (
SELECT *, DENSE_RANK() OVER (ORDER BY hkis_userinfo.points DESC) AS r
FROM "hkis_userinfo")
SELECT * FROM cte
The idea is with_rank() can be changed with filters without
modifying the window.
Without a CTE,
`UserInfo.with_rank.filter(user__username="anyone")`
would always be ranked 1st (as the only one in its selection).
"""
with_rank = With(
self.annotate(r=Window(order_by=F("points").desc(), expression=DenseRank()))
)
return with_rank.queryset().with_cte(with_rank)
class UserInfoManager(CTEManager):
"""UserInfo.with_rank manager (the base one), allows for:
User.objects.first().hkis.r
and:
UserInfo.with_rank.first().r
"""
def get_queryset(self):
return UserInfoCTEQuerySet(self.model, using=self._db).with_rank()
class UserInfo(models.Model):
class Meta:
base_manager_name = "with_rank"
indexes = [
models.Index(fields=["-points"]),
]
objects = CTEManager()
with_rank = UserInfoManager.from_queryset(UserInfoCTEQuerySet)()
user = models.OneToOneField(to=User, on_delete=models.CASCADE, related_name="hkis")
points = models.FloatField(default=0) # Computed sum of solved exercise positions.
def __str__(self):
return f"{self.user.username} {self.points} points"If I create some values, use dumpdata to save them, and loaddata to get them back I'm getting:
django.db.utils.OperationalError: Problem installing fixture '/tmp/cteissue/issue39/fixtures/initial.json': Could not load issue39.UserInfo(pk=1): no such table: cte
I'm having a small reproducer here, just run:
./manage.py loaddata initial
Or if you want to start it from scratch, it looks like:
django-admin startproject cteissue
cd cteissue/
./manage.py startapp issue39
editor issue39/models.py # Paste my model
./manage.py makemigrations
./manage.py migrate
./manage.py createsuperuser
sqlite3 db.sqlite3 <<< 'insert into issue39_userinfo (points, user_id) values (1, 1);'
mkdir issue39/fixtures
./manage.py dumpdata -o issue39/fixtures/initial.json
./manage.py loaddata initial
Full stack trace
$ ./manage.py loaddata initial
Traceback (most recent call last):
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such table: cte
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/tmp/cteissue/./manage.py", line 22, in <module>
main()
File "/tmp/cteissue/./manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/management/commands/loaddata.py", line 78, in handle
self.loaddata(fixture_labels)
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/management/commands/loaddata.py", line 123, in loaddata
self.load_label(fixture_label)
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/management/commands/loaddata.py", line 190, in load_label
obj.save(using=self.using)
File "/home/mdk/.local/lib/python3.9/site-packages/django/core/serializers/base.py", line 223, in save
models.Model.save_base(self.object, using=using, raw=True, **kwargs)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/models/base.py", line 763, in save_base
updated = self._save_table(
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/models/base.py", line 845, in _save_table
updated = self._do_update(base_qs, using, pk_val, values, update_fields,
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/models/base.py", line 899, in _do_update
return filtered._update(values) > 0
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/models/query.py", line 802, in _update
return query.get_compiler(self.db).execute_sql(CURSOR)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1559, in execute_sql
cursor = super().execute_sql(result_type)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1175, in execute_sql
cursor.execute(sql, params)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/mdk/.local/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: Problem installing fixture '/tmp/cteissue/issue39/fixtures/initial.json': Could not load issue39.UserInfo(pk=1): no such table: cte
Metadata
Metadata
Assignees
Labels
No labels