[SQLite][Django] FOREIGN KEY constraint failed

Odpowiedz Nowy wątek
2019-08-13 11:00
0

Czy w tej bazie danych są jakieś błędy? Przy usuwaniu rekordów otrzymuję komunikat 'FOREIGN KEY constraint failed'

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.contrib.auth.models import User
from django.db.models.signals import post_save
import datetime

class ClassCode(models.Model):
    code = models.CharField(max_length=5)

class Role(models.Model):
    name = models.CharField(max_length=100)

class Student(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    pass_changed = models.BooleanField(default=False)
    role_fk = models.ForeignKey(Role, on_delete=models.SET_NULL, null=True, blank=True)
    class_code = models.ForeignKey(ClassCode, on_delete=models.CASCADE)

class Year(models.Model):
    year = models.IntegerField(validators=[MinValueValidator(2000), MaxValueValidator(2099)], default=datetime.datetime.now().year)
    class_code = models.ForeignKey(ClassCode, on_delete=models.CASCADE)

class MonthPayment(models.Model):
    student_fk = models.ForeignKey(Student, on_delete=models.CASCADE)
    class_code = models.ForeignKey(ClassCode, on_delete=models.CASCADE)
    month = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(9)])
    year_fk = models.ForeignKey(Year, on_delete=models.CASCADE)

class Event(models.Model):
    class_code = models.ForeignKey(ClassCode, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    date = models.DateField(blank=True, null=True)
    value = models.DecimalField(decimal_places=2, max_digits=6, validators=[MinValueValidator(0)])

class EventPayment(models.Model):
    event_fk = models.ForeignKey(Event, on_delete=models.CASCADE)
    student_fk = models.ForeignKey(Student, on_delete=models.CASCADE)
    paid = models.BooleanField(default=False)

def create_student(sender, instance, created, **kwargs): # to jest hard coded
    if created:
        Student.objects.create(id=instance.id, user=instance, class_code_id=1, role_fk_id=1)

post_save.connect(create_student, sender=User)

Pozostało 580 znaków

2019-08-13 22:23
0

Może to jest przyczyna:
https://docs.djangoproject.co[...].2/ref/contrib/admin/actions/

The “delete selected objects” action uses QuerySet.delete() for efficiency reasons, which has an important caveat: your model’s delete() method will not be called.
If you wish to override this behavior, you can override ModelAdmin.delete_queryset() or write a custom action which does deletion in your preferred manner – for example, by calling Model.delete() for each of the selected items.

Pozostało 580 znaków

2019-08-13 22:35
0

Pewnie coś z migracjami się zwaliło. Spróbuj jeszcze usnąć normalnie przez ORMa czyli w view pobierz obiekt i go usuń delete()( tak tak głupota ale może pomóc)

Pozostało 580 znaków

2019-08-13 22:36
0

1) W tym Twoim modelu bazodanowym (nie django) nie masz zdefiniowanych FK jako ON DELETE CASCADE, tylko coś w stylu:

FOREIGN KEY("event_fk_id") REFERENCES "klasowe_event"("id") DEFERRABLE INITIALLY DEFERRED,
FOREIGN KEY("student_fk_id") REFERENCES "klasowe_student"("id") DEFERRABLE INITIALLY DEFERRED

2) W SQLLIte jest taki wynalazek jak PRAGMAS i jest też przełącznik (domyślnie wyłączony) dla kluczy obcych. Internety mówią, że dla DELETE CASCADE potrzebujesz PRAGMA foreign_keys=ON.

Pozostało 580 znaków

2019-08-13 22:46
0
yarel napisał(a):

1) W tym Twoim modelu bazodanowym (nie django) nie masz zdefiniowanych FK jako ON DELETE CASCADE, tylko coś w stylu:

FOREIGN KEY("event_fk_id") REFERENCES "klasowe_event"("id") DEFERRABLE INITIALLY DEFERRED,
FOREIGN KEY("student_fk_id") REFERENCES "klasowe_student"("id") DEFERRABLE INITIALLY DEFERRED

I raczej nie będzie, bo z tego co zrozumiałem to django triggeruje usuwanie kaskadowe.

2) W SQLLIte jest taki wynalazek jak PRAGMAS i jest też przełącznik (domyślnie wyłączony) dla kluczy obcych. Internety mówią, że dla DELETE CASCADE potrzebujesz PRAGMA foreign_keys=ON.

Też to widziałem, ale to chyba w czystym sqllite. Jak na moje django powinien to robić za mnie.
Jutro spróbuję usunąć db, wykonać migracje, ew. virtualenv również od nowa.

edytowany 2x, ostatnio: bartox;, 2019-08-13 22:47

Pozostało 580 znaków

2019-08-13 23:07
0

no przecież @Delor wstawił Ci cytat z helpa czemu to nie działa.


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
Niekoniecznie. To jest trop do sprawdzenia. W internetach nie widzę skarg na takie zachowanie panelu admina więc błąd może być w innym miejscu. - Delor 2019-08-13 23:11
Nie wiem czy o to wam Panowie chodzi, ale zrobiłem w kodzie coś takiego: qs = User.objects.filter(pk=5) for user in qs: user.delete() i dalej to samo - bartox; 2019-08-13 23:42

Pozostało 580 znaków

2019-08-14 00:03
0

Trzeba zobaczyć migracje, czy te modele były zrobione raz i migracje czy coś edytowałeś i zrobiłeś kilka migracji dla tych modeli?

Coś było grzebane - bartox; 2019-08-14 00:09
Dodatkowe migracje też były - bartox; 2019-08-14 00:10

Pozostało 580 znaków

2019-08-14 11:42

Zrobiłem nowy projekt. Wrzuciłem Twoje modele.
makemigrate - Ok
migrate - Ok
createsuperuser - constraint failed (brak rekordów aby stworzyć Student w create_student()) ale bez transakcji więc User dodany i można użyć panelu
Po dodaniu odpowiednich rekordów: SOA#1
Działa dodawanie, edycja, usuwanie.
Wykasuj migracje i plik bazy danych (domyślnie db.sqlite3) i zacznij od początku.

edytowany 2x, ostatnio: Delor, 2019-08-14 11:47
Jak na razie działa. Nie mogę chyba modyfikować istniejących modeli... Dzięki za pomoc - bartox; 2019-08-14 14:00

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 0, botów: 1

Robot: CCBot