2013-03-21 14 views
11

Próbuję nauczyć się używać peewee z mysql.Dlaczego peewee zawiera kolumnę 'id' w zapytaniu mysql select?

Mam istniejącą bazę danych na serwerze mysql z istniejącą tabelą. Tabela jest obecnie pusta (właśnie testuję teraz).

>>> db = MySQLDatabase('nhl', user='root', passwd='blahblah') 
>>> db.connect() 


>>> class schedule(Model): 
...  date = DateField() 
...  team = CharField() 
...  class Meta: 
...    database = db 

>>> test = schedule.select() 
>>> test 
<class '__main__.schedule'> SELECT t1.`id`, t1.`date`, t1.`team` FROM `nhl` AS t1 [] 
>>> test.get() 

pojawia się następujący błąd:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/site-packages/peewee.py", line 1408, in get 
    return clone.execute().next() 
    File "/usr/lib/python2.6/site-packages/peewee.py", line 1437, in execute 
    self._qr = QueryResultWrapper(self.model_class, self._execute(), query_meta) 
    File "/usr/lib/python2.6/site-packages/peewee.py", line 1232, in _execute 
    return self.database.execute_sql(sql, params, self.require_commit) 
    File "/usr/lib/python2.6/site-packages/peewee.py", line 1602, in execute_sql 
    res = cursor.execute(sql, params or()) 
    File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 201, in execute 
    self.errorhandler(self, exc, value) 
    File "/usr/lib64/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler 
    raise errorclass, errorvalue 
_mysql_exceptions.OperationalError: (1054, "Unknown column 't1.id' in 'field list'") 

Dlaczego peewee dodając 'id' kolumnę do kwerendy wybierającej? Nie mam kolumny id w tabeli, która już istnieje w bazie danych. Po prostu chcę pracować z istniejącą tabelą i nie polegać na tym, że peewee musi ją tworzyć za każdym razem, gdy chcę wejść w interakcję z bazą danych. Właśnie tam uważam, że błąd.

Wynik zapytania powinien być pusty, ponieważ tabela jest pusta, ale ponieważ się uczę, chciałem tylko wypróbować kod. Doceniam twoją pomoc.

EDIT

podstawie pomocnych odpowiedzi przez Wooble i Franciszka I przychodzą się zastanawiać, czy to jeszcze ma sens dla mnie do korzystania peewee lub innego podobnego SQLAlchemy ORM. Jakie są zalety korzystania z ORM zamiast po prostu uruchamiać bezpośrednie zapytania w Pythonie używając MySQLdb?

To jest to, czego oczekuję, że robi:

zapewnia automatyczną pobierania danych z różnych serwerów internetowych. Większość danych jest w formacie xls lub csv. Mogę przekonwertować xls na csv przy użyciu pakietu xlrd.

-parsowanie/przetwarzanie danych w obiektach listy przed wstawieniem/wstawieniem masowym do tabeli mysql db.

- uruchamianie złożonych zapytań do eksportu danych z mysql do Pythona na odpowiednie uporządkowane dane (na przykład listy) dla różnych obliczeń statystycznych, które są łatwiejsze do zrobienia w pythonie zamiast mysql. Wszystko, co można zrobić w mysql, zostanie wykonane, ale mogę uruchomić złożone regresje w pythonie.

-nowy różne pakiety graficzne na danych pobranych z zapytań. Niektóre z nich mogą obejmować użycie pakietu ggplot2 (z projektu R), który jest zaawansowanym pakietem graficznym. Więc włączę integrację R/Pythona.

Biorąc pod uwagę powyższe - czy najlepiej spędzam godziny na hakowaniu, aby nauczyć się ORM/Peewee/SQLAlchemy lub trzymać się bezpośrednich zapytań mysql przy użyciu MySQLdb?

Odpowiedz

15

Większość prostych ORMów z wzorami aktywnych rekordów wymaga kolumny id do śledzenia tożsamości obiektu. PeeWee wydaje się być jednym z nich (a przynajmniej nie jestem świadomy żadnego sposobu, aby , a nie użyć identyfikatora). Prawdopodobnie nie możesz użyć PeeWee bez zmieniania swoich tabel.

Twoja dotychczasowa tabela nie wydaje się być dobrze zaprojektowana, ponieważ wygląda na to, że brakuje jej klucza lub klucza złożonego. Każda tabela powinna mieć atrybut kluczowy - w przeciwnym razie nie można odróżnić jednego wiersza od drugiego.

Jeśli jedna z tych kolumn jest kluczem podstawowym, spróbuj dodać primary_key=True argumentu jak wyjaśniono in the docs concerning non-integer primary keys

date = DateField(primary_key=True) 

Należy pamiętać, że nie jestem pewien, czy PeeWee będzie zdenerwowany, że klucz podstawowy nie jest nazwany id.

Należy zbadać SQLAlchemy, który wykorzystuje wzorzec mapowania danych. Jest to o wiele bardziej skomplikowane, ale także o wiele potężniejsze. Nie nakłada żadnych ograniczeń na projekt tabeli SQL, a w rzeczywistości może automatycznie odzwierciedlać strukturę tabeli i wzajemne relacje w większości przypadków. (Może nie tak dobrze w MySQL, ponieważ relacje klucza obcego nie są widoczne w domyślnym silniku tabeli). Najważniejsze dla ciebie jest to, że może obsługiwać tabele, które nie mają klucza.

+1

Dziękuję za szczegółową odpowiedź. Jak się okazuje, istniejąca tabela w bazie danych ma KLAWISZ PODSTAWOWY (data). Czy muszę używać pwiz, jak wskazał Wooble, aby dostarczyć te informacje do podglądu? Doceń pomoc. – codingknob

+0

Nie potrzebujesz * do - pwiz to tylko generator kodu i nic nie możesz zrobić sam.Prawdopodobnie po prostu dołącz argument "primary_key = True", jak wyjaśniono [w dokumentach opisujących niecałkowite klucze podstawowe] (http://peewee.readthedocs.org/en/latest/peewee/models.html#non-integer-primary-keys). –

+0

Badam SQLAlchemy, ponieważ peewee nie zrobi tego, co chcę w przyszłości. – codingknob

0

Musisz utworzyć metodę tabeli peewee, aby utworzyć rzeczywistą tabelę bazy danych, zanim zadzwonisz pod numer select(), który utworzy kolumnę identyfikatora w tabeli.

+0

Czy utworzy ona tabelę w mojej faktycznej bazie danych? Mam już tę tabelę w bazie danych. Jestem bardzo zdezorientowany, ponieważ dokumentacja peewee nie jest bardzo przyjazna dla początkujących. – codingknob

+0

Ponadto - czy jest tam przewodnik "krok po kroku"/przykłady jak zrobić coś w rodzaju a) połączyć się z db, b) wstawić rekordy zapisane w obiekcie listy do tabeli, c) wykonać skomplikowane zapytanie (z łączeniami, grupować po itp. .) oraz d) przechowuje wyniki zapytania w obiekcie listy Pythona, który następnie może być używany do innych celów. Dokumentacja peewee nie wyjaśnia w sposób poprawny przypadku użycia końcowego pakietu i jak przejść przez proces roboczy, który opisuję na przykład od a do d. – codingknob

+0

http://peewee.readthedocs.org/en/latest/peewee/example.html. 'Każdy model ma metodę klasy create_table(), która uruchamia instrukcję CREATE TABLE w bazie danych. Utworzy on tabelę zawierającą wszystkie kolumny, klucze obce i indeksy. Zwykle jest to coś, co możesz zrobić tylko raz, po dodaniu nowego modelu. ". Jak ten pakiet może nie działać z istniejącą tabelą? Czy czegoś brakuje? Doceń pomoc. – codingknob

9

Jeśli klucz podstawowy Nazwa kolumna jest inna niż „id” należy dodać dodatkowe pole do tego modelu tabela Klasa:

class Table(BaseModel): 
    id_field = PrimaryKeyField() 

To pokaże swój skrypt, że tabela zawiera podstawowe klucze przechowywane w kolumnie o nazwie "id_field" i ta kolumna jest typu INT z włączoną funkcją Auto Increment. Here to dokumentacja opisująca typy pól w peewee.

Jeśli chcesz mieć większą kontrolę nad swoim polu klucza podstawowego, jak już wspomniano przez Francisa Avila, należy użyć primary_key = true argumentu podczas tworzenia murawę:

class Table(BaseModel): 
    id_field = CharField(primary_key=True) 

Zobacz this link na zakaz całkowitej dokumentacji kluczy podstawowych

+3

Autor peewee tutaj - Twoja odpowiedź jest na miejscu, dzięki! – coleifer

3

Musisz podać pole primary_key dla tego modelu. Jeśli twoja tabela nie ma pojedynczego pola głównego (podobnie jak moje), pomocna będzie zdefiniowana w Meta CompositeKey.

primary_key = peewee.CompositeKey('date', 'team') 
+0

Zaktualizowałem odpowiedź, teraz jest to jasne. Po prostu znalazłem sposób na stworzenie klucza złożonego. – ySJ