Pymongo, einfache Probs die man nicht erkennt-Bitte um Hilfe

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Benutzeravatar
JayOne
User
Beiträge: 22
Registriert: Mittwoch 12. Dezember 2012, 11:37

Hallo Zusammen,

ich schreibe mir gerade ein kleines Prog mit Anbidung an MongoDB, nun ist es fast fertig und ich sitze hier wie ein Ochs vorm Tor bei einem (denke ich mal) ziemlich einfachern Problem und komme nicht weiter.

Hier mal der Code:

Code: Alles auswählen

import pymongo
import time

class diaryDB:
    def __init__(self):
        self.connection = pymongo.Connection('localhost', 27017)
        self.db = self.connection['diary']
        self.collection = self.db['diary_entry']

    def insert(self, topic='empty', post='empty'):
        insert = {'Topic': topic,
                  'Post': post,
                  'made': time.strftime("%Y, %a the %d th at %H:%M")}
        self.collection.save(insert)
        
    def take(self):
        counter = self.collection.count()
        if counter == 0:
            pass
        else:
            x = 1
            base  = {}
            for i in self.collection.find():
                base.update({x:[i['Topic'], i['Post'], i['made']]})
                x += 1
            return base
                        

Code: Alles auswählen

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
    return self.func(*args)
  File "**********/Documents/Aptana Studio 3 Workspace/Diary2.0/window.py", line 62, in make_entries
    self.but_left['command'] = database.diaryDB.insert(self, top_ic.get(), self.window.get('1.0', 'end'))
  File "********/Documents/Aptana Studio 3 Workspace/Diary2.0/database.py", line 20, in insert
    self.collection.save(insert)
AttributeError: 'diary_entry' object has no attribute 'collection'
Eine Verbidung zur pymongo DB ist hergestellt, eine DB angelegt und eine Collection erstellt und nun meckert er beim Einfügen rum.
Ich würde mich freuen wenn mir da jemand sagen kann wo ich den Fehler habe, denn ich sehe ihn nicht.

Danke im Voraus.
Faus 2, Akt 1: ...alles kann der Edle leisten, der versteht und rasch begreift...
BlackJack

@JayOne: Ich weiss gar nicht wo ich da anfangen soll. `command` von `Button`\s muss an eine *Funktion* gebunden werden. Du bindest es an den *Rückgabewert* der `diaryDB.insert()`-Methode. Und diese Methode rufst Du anscheinend auf der Klasse auf, wobei Du als `self` ein ganz anderes Objekt übergibst. Eines das wie die Fehlermeldung deutlich sagt kein `collection`-Attribut besitzt. Der (?) Fehler sitzt also in Quelltext den Du gar nicht gezeigt hast.

Auch der gezeigte Quelltext ist nicht so schön bis leicht schräg. Bei der Namensgebung sollte man sich mindestens bei den Klassennamen an den Style Guide for Python Code halten. Dann wäre beim `diaryDB.insert()` schon beim Lesen aufgefallen, dass das Unsinn ist.

Die Namen sind auch sonst teilweise unglücklich gewählt. Das `insert` in der `insert()`-Methode ist eigentlich ein Eintrag. Der `counter` in `take()` ist kein Zähler sondern eine Anzahl und müsste deshalb `count` heissen. Das könnte man sich aber auch sparen und gleich über `collection.find()` iterieren. Wenn nichts gefunden wird, dann gibt man halt ein leeres Wörterbuch zurück. Das wäre auch eine viel regelmässigere API als das implizite `None` für diesen Fall.

Das durchnummerieren der Einträge kann man mit der `enumerate()`-Funktion einfacher haben und `dict.update()` zum Hinzufügen eines *einzigen* Eintrags zu verwenden ist reichlich umständlich. Warum das Wörterbich `base` heisst, erschliesst sich mir jetzt nicht. Und `i` in einer Schleife an etwas anderes als ganze Zahlen zu binden verwirrt Leser. Ein beschreibenderer Name wäre nett.
Benutzeravatar
JayOne
User
Beiträge: 22
Registriert: Mittwoch 12. Dezember 2012, 11:37

Die Bezeichnungen habe ich geändert und angepasst und für den Fehler bei der Funktionsbindung bei Button lasse ich mir auch was neues einfallen.

Nur frage ich mich wie ich anders als über self. auf die collection zugreifen soll. Mit self. sorge ich doch dafür collection für die ganze Klasse verfügbar zu machen, oder nicht? Von daher weiss ich momentan leider nicht wie ich dass anders als so machen soll.
Faus 2, Akt 1: ...alles kann der Edle leisten, der versteht und rasch begreift...
BlackJack

@JayOne: In der Klasse die Du gezeigt hast kann man das so machen, nur verwendest Du das falsch. Du musst die Methode auf einem Exemplar aufrufen und nicht auf der Klasse und dort selbst etwas für `self` übergeben was gar kein Exemplar von dieser Klasse ist und damit halt auch kein `collections`-Attribut besitzt.
Benutzeravatar
JayOne
User
Beiträge: 22
Registriert: Mittwoch 12. Dezember 2012, 11:37

Ok habs raus, danke für die Hinweise :-)
Faus 2, Akt 1: ...alles kann der Edle leisten, der versteht und rasch begreift...
Antworten