Django ORM crée un alias fantôme dans une jointure SQL
-
06-07-2019 - |
Question
J'exécute le code suivant (les noms ont été modifiés pour protéger les innocents, la structure du modèle peut sembler bizarre):
memberships =
models.Membership.objects.filter(
degree__gt=0.0,
group=request.user.get_profile().group
)
exclude_count =
memberships.filter(
member__officerships__profile=request.user.get_profile()
).count()
if exclude_officers_with_profile:
memberships = memberships.exclude(
member__officerships__profile=request.user.get_profile()
)
total_count = memberships.count()
qui à ce stade aboutit à:
OperationalError at /
(1054, "Unknown column 'U1.id' in 'on clause'")
Le code SQL généré est:
SELECT
COUNT(*)
FROM
`membership`
WHERE (
`membership`.`group_id` = 2 AND
`membership`.`level` > 0.0 AND
NOT (
`membership`.`member_id`
IN (
SELECT
U2.`member_id`
FROM
`membership` U0 INNER JOIN `officers` U2
ON (U1.`id` = U2.`member_id`)
WHERE U2.`profile_id` = 2
)
)
)
Il semble que l'instruction ON de la jointure SQL fasse référence à un alias qui n'a pas été défini. Des idées pourquoi !? J'ai abandonné ma base de données MySQL et j'ai resynchronisé les tables de mes modèles pour essayer de m'assurer qu'il n'y avait aucune incohérence.
La structure des modèles que j'utilise est la suivante:
class Membership(models.Model):
member = models.ForeignKey(Member, related_name='memberships')
group = models.ForeignKey(Group, related_name='memberships')
level = models.FloatField(default=0.0)
class Member(models.Model):
name = models.CharField(max_length=32)
class Officer(models.Model):
member = models.ForeignKey(Member, related_name='officerships')
profile = models.ForeignKey(UserProfile)
class UserProfile(models.Model)
group = models.ForeignKey(Group)
class Group(models.Model)
pass
La solution
Je pense que cela pourrait être un symptôme de:
http://code.djangoproject.com/ticket/9188
qui a été corrigé à partir de la révision django 9589, je pense. Maintenant, comment savoir sur quelle révision je travaille ...
Confirmé. Lorsque j'ai mis en œuvre le changement référencé dans le ticket ci-dessus:
http://code.djangoproject.com/changeset/9589
mon erreur est partie.