2009-03-03 12 views
19
class dbview(models.Model): 
    # field definitions omitted for brevity 
    class Meta: 
     db_table = 'read_only_view' 

def main(request): 
    result = dbview.objects.all() 

Caught wyjątek podczas renderowania: (1054, "Nieznana kolumna 'read_only_view id' w 'liście pól'")Django: Zapytania tylko do odczytu zobaczyć bez klucza podstawowego

Jest brak klucza podstawowego Widzę w widoku. Czy jest w pobliżu praca?

Komentarz:
Nie mam kontroli nad widokiem, do którego uzyskuję dostęp za pomocą Django. Przeglądarka MySQL wyświetla tam kolumny, ale nie ma klucza głównego.

Odpowiedz

17

Kiedy mówisz „nie mam kontroli nad widzenia jestem korzystającego z Django. Przeglądarka MySQL wyświetla tam kolumny, ale nie ma klucza głównego. "

Zakładam, że masz na myśli, że jest to starsza tabela i nie masz prawa dodawać ani zmieniać kolumn?

Jeśli tak, tak naprawdę nie istnieje klucz podstawowy (nawet kolumna lub kolumna inna niż domyślna *), to tabela nie została skonfigurowana bardzo dobrze, a wydajność może znacznie pogorszyć wydajność.

Nie ma to jednak znaczenia dla Ciebie. Potrzebujesz tylko kolumny, która z pewnością będzie unikatowa dla każdego wiersza. Ustaw, aby w modelu był "primary_key = True", a Django będzie szczęśliwy.

  • Jest jeszcze jedna możliwość, która może być problematyczna. Jeśli nie ma kolumny, która jest gwarantowana jako unikalna, tabela może wykorzystywać złożone klucze podstawowe. To znaczy - określa, że ​​dwie kolumny razem wzięte będą zapewniać unikalny klucz podstawowy. Jest to całkowicie poprawne modelowanie relacyjne, ale niestety nieobsługiwane przez Django. W takim przypadku nie można zrobić wiele oprócz surowego SQL, chyba że można dodać kolejną kolumnę.
+0

Dziękuję bardzo, to jest naprawdę bardzo pomocne! – dmi

+0

Bardzo pomocny. Jedna rzecz do dodania; jeśli kolumna, której chcesz użyć dla klucza podstawowego, jest typu CHAR, nie może być dłuższa niż 255 znaków. –

+6

To naprawdę nie rozwiązuje problemu, który dotyczy widoku db, a nie tabeli. Podałeś jedno ze swoich pól jako pk dla django, niezależnie od tego, czy jest, czy nie. Możesz tego uniknąć, ponieważ nigdy nie będzie żadnego wstawienia/aktualizacji relacji przez ORM. Zobacz [odpowiedź od Davida S] (http://stackoverflow.com/a/11594959/519015) i mój komentarz na ten temat, aby dowiedzieć się więcej o tej technice. –

1

Powinno być automatycznie wygenerowane pole id po uruchomieniu syncdb (jeśli nie ma klucza podstawowego zdefiniowanego w modelu, wówczas Django wstawi dla ciebie AutoField).

Ten błąd oznacza, że ​​Django pyta o bazę danych dla pola id, ale nie istnieje. Czy możesz uruchomić django manage.py dbshell, a następnie DESCRIBE read_only_view; i opublikować wynik? Spowoduje to wyświetlenie wszystkich kolumn znajdujących się w bazie danych.

Czy można uwzględnić definicję modelu, którą wykluczono? (i upewnij się, że nie zmieniłeś definicji modelu, ponieważ wykonałeś syncdb?)

+0

Dzięki, powinienem był to wyjaśnić na samym początku. Zobacz aktualizację. – dmi

+0

Nie pytam, aby zobaczyć wiersz, do którego wchodzisz, chcę tylko zobaczyć twoją definicję modelu (nie to samo). – obeattie

+0

Definicje modeli są następujące: text = models.CharField() Jednak nie mogę zdefiniować pola z "primary_key = True", ponieważ widok nie ma klucza podstawowego. – dmi

12

Mam ten problem przez cały czas. Mam pogląd, że nie mogę lub nie chcę się zmieniać, ale chcę mieć stronę wyświetlającą złożone informacje (być może w sekcji administracyjnej). I tylko przesłonić uratować i wychować NotImplementedError:

def save(self, **kwargs): 
     raise NotImplementedError() 

(choć to chyba nie potrzebne w większości przypadków, ale to sprawia, że ​​czuję się nieco lepiej)

ja również ustawić udało się Fałsz w Meta klasa.

class Meta: 
     managed = False 

Następnie wybieram dowolne pole i oznaczam jako klucz podstawowy. Nie ma znaczenia, czy jest naprawdę wyjątkowy, robisz filtry do wyświetlania informacji na stronie, itp.

Wydaje się działać dobrze dla mnie. Proszę podać, jeśli są jakieś problemy z tą techniką, które przeoczyłem.

+2

Możesz oznaczyć nieunikalne pole jako klucz podstawowy dla dostępu tylko do odczytu, ale ma to wpływ na rzeczy takie jak 'queryset.distinct(). Count()' i porównania instancji. Aby obejść ten problem, możesz przedefiniować '__eq __()' na modelu. –

+0

Coś, co możesz zrobić dla widoku, jeśli chcesz mieć identyfikator, należy użyć funkcji 'row_number()' (przynajmniej w PostgreSQL). 'SELECT row_number() OVER (pole ORDER BY ASC) AS id,' – Bobort

Powiązane problemy