Otrzymałem wiele błędów związanych z komunikatem:
"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"
po zmianie z python-psycopg na python-psycopg2 jako silnik bazy danych projektu Django.
Kod pozostaje ten sam, po prostu nie wiem, skąd pochodzą te błędy.
python
django
postgresql
psycopg2
Jacek
źródło
źródło
conn.rollback()
(gdzie conn jest twoim obiektem połączenia) usunie błąd, abyś mógł uruchamiać inne zapytaniaOdpowiedzi:
To właśnie robi postgres, gdy zapytanie powoduje błąd i próbujesz uruchomić inne zapytanie bez uprzedniego wycofania transakcji. (Możesz to potraktować jako funkcję bezpieczeństwa, która ochroni Cię przed uszkodzeniem danych).
Aby to naprawić, musisz dowiedzieć się, gdzie w kodzie jest wykonywane złe zapytanie. Pomocne może być użycie opcji log_statement i log_min_error_statement na serwerze postgresql.
źródło
Aby pozbyć się błędu, wycofaj ostatnią (błędną) transakcję po naprawieniu kodu:
Możesz użyć try-wyjątkiem, aby zapobiec wystąpieniu błędu:
Patrz: dokumentacja Django
źródło
IntegrityError
a nie klasy podstawowejDatabaseError
?Natknąłem się na ten sam problem. Problem, który tutaj miałem, polegał na tym, że moja baza danych nie była odpowiednio zsynchronizowana. Proste problemy zawsze wydają się powodować największy niepokój ...
Aby zsynchronizować db django, w katalogu aplikacji, w terminalu wpisz:
Edycja: Zauważ, że jeśli używasz django-south, uruchomienie polecenia „$ python manage.py migrate” może również rozwiązać ten problem.
Miłego kodowania!
źródło
python manage.py migrate <app>
... dla wszystkich moich aplikacji.django-south
-migrate
polecenie nie jest wbudowane w django.W Flask musisz tylko napisać:
Dokumentacja PS znajduje się tutaj https://www.postgresql.org/docs/9.4/static/sql-rollback.html
źródło
Z mojego doświadczenia wynika, że te błędy występują w następujący sposób:
W drugim zapytaniu nie ma nic złego, ale ponieważ wychwycono prawdziwy błąd, drugie zapytanie jest tym, które powoduje błąd (znacznie mniej informacyjny).
edycja: dzieje się tak tylko wtedy, gdy
except
klauzula zostanie złapanaIntegrityError
(lub inny wyjątek bazy danych niskiego poziomu), jeśli złapiesz coś takiego,DoesNotExist
ten błąd nie pojawi się, ponieważDoesNotExist
nie spowoduje to uszkodzenia transakcji.Lekcja tutaj to nie próbuj / z wyjątkiem / pass.
źródło
Myślę, że wzorzec wspomniany przez priestc jest bardziej prawdopodobną przyczyną tego problemu podczas używania PostgreSQL.
Wydaje mi się jednak, że wzorzec jest prawidłowy i nie sądzę, że ten problem powinien być powodem do tego, aby go zawsze unikać. Na przykład:
Jeśli czujesz się dobrze z tym wzorcem, ale chcesz uniknąć jawnego kodu obsługi transakcji w dowolnym miejscu, możesz rozważyć włączenie trybu automatycznego zatwierdzania (PostgreSQL 8.2+): https://docs.djangoproject.com/en/ dev / ref / databases / # autocommit-mode
Nie jestem pewien, czy istnieją ważne względy dotyczące wydajności (lub jakiegokolwiek innego rodzaju).
źródło
Jeśli otrzymasz to w interaktywnej powłoce i potrzebujesz szybkiej poprawki, wykonaj następujące czynności:
pierwotnie widoczne w tej odpowiedzi
źródło
Podobne zachowanie spotkałem podczas nieprawidłowo działającej transakcji na
postgres
terminalu. Po tym nic nie przeszło, ponieważdatabase
jest w stanieerror
. Jednak tak szybko, jak można tego uniknąćrollback transaction
. Następujący zrobił dla mnie lewę:COMMIT;
źródło
Mam problem z silimarem. Rozwiązaniem była migracja bazy danych (
manage.py syncdb
lubmanage.py schemamigration --auto <table name>
jeśli korzystasz z południa).źródło
po prostu użyj wycofania
Przykładowy kod
źródło
Właśnie miałem ten błąd, ale maskował on inny, bardziej odpowiedni komunikat o błędzie, w którym kod próbował zapisać ciąg znaków o długości 125 znaków w kolumnie o długości 100 znaków:
Musiałem debugować przez kod, aby powyższa wiadomość się pojawiła, w przeciwnym razie zostanie wyświetlona
źródło
W odpowiedzi na @priestc i @Sebastian, co jeśli zrobisz coś takiego?
Właśnie wypróbowałem ten kod i wydaje się, że działa, po cichu zawiesza się bez konieczności dbania o ewentualne błędy i działa, gdy zapytanie jest poprawne.
źródło
Uważam, że odpowiedź @ AnujGupta jest poprawna. Jednak wycofanie może samo w sobie wywołać wyjątek, który należy złapać i obsługiwać:
Jeśli okaże się, że przepisujesz ten kod w różnych
save()
lokalizacjach, możesz wyodrębnić metodę:Na koniec możesz go upiększyć za pomocą dekoratora, który chroni metody wykorzystujące
save()
:Nawet jeśli implementujesz dekorator powyżej, nadal wygodnie jest zachować go
try_rolling_back()
jako wyodrębnioną metodę na wypadek, gdybyś musiał użyć go ręcznie w przypadkach, w których wymagana jest specyficzna obsługa, a ogólna obsługa dekoratora nie jest wystarczająca.źródło
To jest dla mnie bardzo dziwne zachowanie. Dziwi mnie, że nikt nie pomyślał o punktach zapisu. W moim kodzie nie można było oczekiwać zapytania:
Zmieniłem kod w ten sposób, aby używać punktów zapisu:
źródło
W muszli Flask wszystko, co musiałem zrobić, to
session.rollback()
ominąć to.źródło
Rozwiązałem ten problem, błąd pojawia się, ponieważ transakcje błędów nie zostały poprawnie zakończone, znalazłem tutaj
postgresql_transactions
polecenie kontroli transakcjiKontrola transakcji
Poniższe polecenia służą do kontrolowania transakcji
więc używam
END TRANSACTION
do zakończenia błędu TRANSAKCJA, kod taki jak ten:źródło
możesz wyłączyć transakcję poprzez „set_isolation_level (0)”
źródło