Adressdatenbank

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mittwoch 12. Juli 2006, 07:06

Hallo,

da ich mir derzeit eine Adressdatenbank schreib - obwohl Gerold derzeit eine schreibt, um PySQLite zu erklären. Treten ja immer ein paar Probleme auf :D
Sicherlich hab ich ja auch schon einen, sonst gäbs den Thread hier nich :wink:
Also Fehler:

Code: Alles auswählen

$ python Adressenverwaltung.py
INSERT INTO adresses (
                vorname,
                zuname,
                nachname,
                anrede,
                adresse,
                plz,
                ort,
                land,
                privatnummer,
                privatfaxnummer,
                mobilnummer,
                bueronummer,
                buerofaxnummer
            ) VALUES (
                Max,
                Maximilian,
                Musterman,
                Herr,
                Musterstr 12,
                1234865,
                Musterstadt,
                Deutschland,
                004912326548,
                /,
                01701234586,
                /,
                /)
Traceback (most recent call last):
  File "Adressenverwaltung.py", line 154, in ?
    main()
  File "Adressenverwaltung.py", line 149, in main
    adr.add('Max','Maximilian','Musterman','Herr','Musterstr 12','1234865','Musterstadt',
'Deutschland','004912326548','/','01701234586','/','/')
  File "Adressenverwaltung.py", line 107, in add
    self.cur.execute(sql)
pysqlite2.dbapi2.OperationalError: near "12": syntax error
Der Dazugehörige Codeabschnitt

Code: Alles auswählen

    def add (self,
             vorname = None, zuname = None, nachname = None, anrede = None, adresse = None, plz = None, ort = None, land = None,
             privatnummer = None, privatfaxnummer = None, mobilnummer = None, bueronummer = None, buerofaxnummer = None
        ):
        '''Fügt einen neuen Kontakt in das Adressbuch ein

            :param vorname: Der Vorname des Kontakts
            :param zuname: Der Zuname des Kontakts
            :param nachname: Der Nachname des Kontakts
            :param anrede: Die Anrede des Kontakts
            :param adresse: Die Adresse der Kontakts (Incl. Hausnummer)
            :param plz: Die Postleitzahl des Kontakts
            :param ort: Der Ort/Wohnort des Kontakts
            :param land: Das Land, in welchem der Kontakt wohnt
            :param privatnummer: Die Privatnummer des Kontakts
            :param privatfaxnummer: Die Privatfaxnummer des Kontakts
            :param mobilnummer: Die Mobiltelefonnummer des Kontakts
            :param bueronummer: Die Büronummer des Kontakts
            :param buerofaxnummer: Die Bürofaxnummer des Kontakts
        '''

        sql = '''INSERT INTO adresses (
                vorname,
                zuname,
                nachname,
                anrede,
                adresse,
                plz,
                ort,
                land,
                privatnummer,
                privatfaxnummer,
                mobilnummer,
                bueronummer,
                buerofaxnummer
            ) VALUES (
                %s,
                %s,
                %s,
                %s,
                %s,
                %s,
                %s,
                %s,
                %s,
                %s,
                %s,
                %s,
                %s)''' % (vorname, zuname, nachname, anrede, adresse, plz, ort, land,
privatnummer, privatfaxnummer, mobilnummer, bueronummer, buerofaxnummer)
        print sql #daher kommt die lange SQL ausgabe oben :wink:

        self.cur.execute(sql)
        self.con.commit()
Kann mir da einer helfen?
Ich versteh nich, wo da der Syntaxerror sien soll
BlackJack

Mittwoch 12. Juli 2006, 07:37

Dein SQL ist fehlerhaft. Das ist im Grunde der gleiche Fehler, den Du auch unter Python bekommen würdest:

Code: Alles auswählen

In [3]: a = Musterstrasse 12
------------------------------------------------------------
   File "<ipython console>", line 1
     a = Musterstrasse 12
                        ^
SyntaxError: invalid syntax
Bevor Du jetzt anfängst ``'%s', '%s', ...`` in Deinen Quelltext zu schreiben -- lass es. Gib den SQL Befehl so wie er ist als erstes Argument an `execute()` und die Werte als zweiten. Dann sorgt das DB Modul dafür, dass die vernünftig in den SQL Befehl eingefügt werden.

Insbesondere passiert dann auch kein Murks wenn jemand 'Müller's Backerei' eintragen will oder gar jemand absichtlich "bösen" SQL-Code eingibt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 12. Juli 2006, 07:41

CrackPod hat geschrieben:Ich versteh nich, wo da der Syntaxerror sien soll
Hi CrackPod!

Die korrekte Syntax zum Einfügen von Textfeldern ist folgende:

Code: Alles auswählen

INSERT INTO adresses (
  vorname,
  zuname
) VALUES (
  'Max',
  'Maximilian'
)
Achte auf die einfachen Anführungszeichen.

Folgendes Codebeispiel kann so nicht funktionieren, da es sich nicht um die Anfürhungszeichen kümmert:

Code: Alles auswählen

sql = """
INSERT INTO adresses (
  vorname,
  zuname
) VALUES (
  %s,
  %s
)
""" % (vorname, zuname)
Die %s in Anführungszeichen zu setzen ist auch keine Lösung, da du auch None übergeben können musst. Aber None darf nicht in Anführungszeichen gesetzt werden.

Also hast du mehrere Möglichkeiten. Entweder du kümmerst dich selbst darum,

Code: Alles auswählen

if vorname:
    vorname = "'%s'" % vorname
else:
    vorname = "None"
oder du lässt es dir von pysqlite erledigen.

Code: Alles auswählen

sql = """
INSERT INTO adresses (
  vorname,
  zuname
) VALUES (
  :vorname,
  :zuname
)
"""
cur.execute(sql, {"vorname": vorname, "zuname": zuname})
Achte auf die Doppelpunkte vor den Variablenamen im SQL-String.

So kümmert sich pysqlite um die Anfürhrungszeichen, wo sie benötigt werden. None und Zahlen werden nicht in Anfürhungszeichen eingeschlossen.

Da sich pysqlite um das alles kümmert, ist es für andere viel schwerer, Code in die SQL-Anweisung einzuschmuggeln. (Stichwort: SQL-Injection)

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mittwoch 12. Juli 2006, 12:00

auf das mit den Anführungszeichen bin ch kurz nachdem ich gepostet hab selber gekommen, hab haber vergessen, den Post zu löschen(is aber vorteilhaft :D hab nen neuen Trick gelernt)
Danke
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mittwoch 12. Juli 2006, 12:23

Naja, hab trotzdem noch Probleme:
Fehler

Code: Alles auswählen

$ python Adressenverwaltung.py
INSERT INTO adresses (
                vorname,
                zuname,
                nachname,
                anrede,
                adresse,
                plz,
                ort,
                land,
                privatnummer,
                privatfaxnummer,
                mobilnummer,
                bueronummer,
                buerofaxnummer
            ) VALUES (
                :vorname,
                :zuname,
                :nachname,
                :anrede,
                :adresse,
                :plz,
                :ort,
                :land,
                :privatnummer,
                :privatfaxnummer,
                :mobilnummer,
                :bueronummer,
                :buerofaxnummer)
Es ist ein Fehler beim Erstellen des Kontakts aufgetreten adresses.id may not be NULL
Methode:

Code: Alles auswählen

        sql = '''INSERT INTO adresses (
                vorname,
                zuname,
                nachname,
                anrede,
                adresse,
                plz,
                ort,
                land,
                privatnummer,
                privatfaxnummer,
                mobilnummer,
                bueronummer,
                buerofaxnummer
            ) VALUES (
                :vorname,
                :zuname,
                :nachname,
                :anrede,
                :adresse,
                :plz,
                :ort,
                :land,
                :privatnummer,
                :privatfaxnummer,
                :mobilnummer,
                :bueronummer,
                :buerofaxnummer)'''
        print sql

        self.cur.execute(sql,{'vorname':vorname, 'zuname':zuname, 'nachname':nachname, 'anrede':anrede, 'adresse':adresse, 'plz':plz,
                              'ort':ort, 'land':land, 'privatnummer':privatnummer, 'privatfaxnummer':privatfaxnummer,
                              'mobilnummer':mobilnummer, 'bueronummer':bueronummer, 'buerofaxnummer':buerofaxnummer}
                         )
        self.con.commit()
Aufruf

Code: Alles auswählen

adr = Adress('./daten/adress.sqldb')
adr.add('Max','Maximilian','Musterman','Herr','Musterstr 12',
'1234865','Musterstadt','Deutschland','004912326548',
'','01701234586','','')
Muss ich das Feld id mit angeben bzw einfügen? Bei MySQL muss man das nicht :| (Falls man der id AUTO_INCREMENT gegeben hat - was ich gemacht hab)
Datenbankstruktur:

Code: Alles auswählen

CREATE TABLE adresses(
      id INTEGER PRYMARY KEY AUTO_INCREMENT NOT NULL,
      vorname VARCHAR(30),
      zuname VARCHAR(40),
      nachname VARCHAR(30),
      anrede VARCHAR(20),
      adresse VARCHAR(50),
      plz VARCHAR(15),
      ort VARCHAR(25),
      land VARCHAR(30),
      privatnummer VARCHAR(35),
      privatfaxnummer VARCHAR(35),
      mobilnummer VARCHAR(35),
      bueronummer VARCHAR(35),
      buerofaxnummer VARCHAR(35)
)
(Und warum geht das nich, wenn ich noch IF NOT EXISTS mit dazu mach, dann bekomm ich nen 'SyntaxError near "NOT"'....)


Noch was anderes: Wie bekomm ich es hin, keine Werte übergeben zu müssen? Wenn ich satt ,'','') (im letzten Teil) ,,) schreib, bekomm ich nen Syntaxerror-.- Geht das nich auch noch anders, als einen leeren String zu übergeben?

Danke greetz
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 12. Juli 2006, 12:33

CrackPod hat geschrieben:Es ist ein Fehler beim Erstellen des Kontakts aufgetreten adresses.id may not be NULL

Code: Alles auswählen

CREATE TABLE adresses(
      id INTEGER PRYMARY KEY AUTO_INCREMENT NOT NULL,
      ...
Hi CrackPod!

Bei SQLite gibt es kein AUTO_INCREMENT. Es wird einfach ignoriert. Wichtig ist einzig "INTEGER PRIMARY KEY". Das ist das Zeichen für SQLite, dass automatisch hoch gezählt wird. (du hast dich nur verschrieben...)

Siehe dieses Beispiel: http://gelb.bcom.at/trac/misc/browser/s ... rev=11#L99

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 12. Juli 2006, 12:38

CrackPod hat geschrieben:Noch was anderes: Wie bekomm ich es hin, keine Werte übergeben zu müssen? Wenn ich satt ,'','') (im letzten Teil) ,,) schreib, bekomm ich nen Syntaxerror-.- Geht das nich auch noch anders, als einen leeren String zu übergeben?
Hi CrackPod!

In der Deklaration der Funktion hast du für diese Parameter einen Standardwert übergeben. Das bedeutet, dass du diese restlichen Argumente einfach weg lassen kannst. Keinen Beistrich und keine Anführungszeichen.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mittwoch 12. Juli 2006, 12:41

Achso... So is das :wink:
Danke!

Zu deinem Link: Den kenn ich, aber ich schaus mir nich allzu oft an, weil ich ja nich alles vorgekaut bekommen will. Mit der Datenbankerstellung hab ich schon reingeschaut und mich gefragt, wie das bei dir denn ohne AUTO_INCREMENT funzt :D
Wieso geht das IF NOT EXISTS bei mir nicht, wenn ich ne Datenbank erstell?

Code: Alles auswählen

    def install(self):
        sql = '''CREATE TABLE adresses IF NOT EXISTS(
                id INTEGER PRIMARY KEY NOT NULL,
                vorname VARCHAR(30),
                zuname VARCHAR(40),
                nachname VARCHAR(30),
                anrede VARCHAR(20),
                adresse VARCHAR(50),
                plz VARCHAR(15),
                ort VARCHAR(25),
                land VARCHAR(30),
                privatnummer VARCHAR(35),
                privatfaxnummer VARCHAR(35),
                mobilnummer VARCHAR(35),
                bueronummer VARCHAR(35),
                buerofaxnummer VARCHAR(35)
            )'''
        self.cur.execute(sql)
        self.con.commit()
$ python Adressenverwaltung.py
Traceback (most recent call last):
File "Adressenverwaltung.py", line 154, in ?
main()
File "Adressenverwaltung.py", line 145, in main
adr.install()
File "Adressenverwaltung.py", line 52, in install
self.cur.execute(sql)
pysqlite2.dbapi2.OperationalError: table adresses already exists

Code: Alles auswählen

    def install(self):
        sql = '''CREATE TABLE IF NOT EXISTS adresses(
                id INTEGER PRIMARY KEY NOT NULL,
                vorname VARCHAR(30),
                zuname VARCHAR(40),
                nachname VARCHAR(30),
                anrede VARCHAR(20),
                adresse VARCHAR(50),
                plz VARCHAR(15),
                ort VARCHAR(25),
                land VARCHAR(30),
                privatnummer VARCHAR(35),
                privatfaxnummer VARCHAR(35),
                mobilnummer VARCHAR(35),
                bueronummer VARCHAR(35),
                buerofaxnummer VARCHAR(35)
            )'''
        self.cur.execute(sql)
        self.con.commit()
$ python Adressenverwaltung.py
Traceback (most recent call last):
File "Adressenverwaltung.py", line 154, in ?
main()
File "Adressenverwaltung.py", line 145, in main
adr.install()
File "Adressenverwaltung.py", line 52, in install
self.cur.execute(sql)
pysqlite2.dbapi2.OperationalError: near "NOT": syntax error
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 12. Juli 2006, 13:01

CrackPod hat geschrieben:

Code: Alles auswählen

    def install(self):
        sql = '''CREATE TABLE IF NOT EXISTS adresses(
                id INTEGER PRIMARY KEY NOT NULL,
                vorname VARCHAR(30),
Hi CrackPod!

Den einzigen Unterschied, den ich erkenne: Das Leerzeichen zwischen addresses und der Klammer.

Code: Alles auswählen

CREATE TABLE IF NOT EXISTS addresses (
    id INTEGER PRIMARY KEY NOT NULL,
    salutation VARCHAR(50),
Ob das der ausschlaggebende Grund für den Fehler ist?

Nein, das habe ich soeben ausprobiert. Das Leerzeichen ist nicht der Grund.

lg
Gerold
:-)

PS: http://www.woerterbuch.info/?query=Adressen&s=dict ;-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mittwoch 12. Juli 2006, 13:14

Ja aber an was liegst denn dann?
An dem Leerzeichen liegst nich und auch an dem fehlendem 2. d liegst nich :wink:

Ach man :( Will das nich immer überprüfen müssen, obs die Tabelle schon gibt, wenn ein User install macht, obwohls gar nich notwendig ist>.<
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 12. Juli 2006, 13:27

CrackPod hat geschrieben:Ja aber an was liegst denn dann?
Hi CrackPod!

Ich habs. :-)

IF NOT EXISTS funktionert erst ab SQLite Version 3.3.0.

http://www.sqlite.org/changes.html

Hätte ich das vorher gewusst, dann hätte ich es nicht in mein Beispiel rein getan. Ich werde mir also für mein Beispiel etwas anderes ausdenken.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 12. Juli 2006, 13:30

... ach was solls :-)

Ich werde es nicht austauschen. "IF NOT EXISTS" bleibt im Beispiel. Aber einen Hinweis auf diese Version werde ich rein schreiben.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mittwoch 12. Juli 2006, 14:00

und wie kann man das mit älteren versionen überprüfen?
Mann ka ja geschachtelete try...catch Blöcke nehmen.
Der erste versucht ...IF NOT EXISTS...
Wenn das fehlschlägt kommt im Expect ein Try, das schaut, ob man einen Datensatz aus der Tabelle holen kann, wenn ein Tabellenfehler entseht(pysqlite2.dbapi2.OperationalError: no such table: addresses) Dann erstellt man die Tabelle.
War das verständlich:?:
Würde das so funzen?

Greetz

EDIT:
Hab das jetz mal so gemacht:

Code: Alles auswählen

    def install(self):
        '''Erstellt die Datenbankstruktur'''

        
        sql = '''CREATE TABLE IF NOT EXISTS addresses (
                id INTEGER PRIMARY KEY NOT NULL,
                vorname VARCHAR(30),
                zuname VARCHAR(40),
                nachname VARCHAR(30),
                anrede VARCHAR(20),
                adresse VARCHAR(50),
                plz VARCHAR(15),
                ort VARCHAR(25),
                land VARCHAR(30),
                privatnummer VARCHAR(35),
                privatfaxnummer VARCHAR(35),
                mobilnummer VARCHAR(35),
                bueronummer VARCHAR(35),
                buerofaxnummer VARCHAR(35)
            )'''

        try:
            self.cur.execute(sql)
            self.con.commit()
        except sqlite3.OperationalError, err:
            sql = '''SELECT vorname FROM addresses'''
            try:
                self.cur.execute(sql)
                self.con.commit()
            except sqlite3.OperationalError, err:
                error = str(err)
                if error.startswith('no such table:'):
                    sql = '''CREATE TABLE addresses (
                            id INTEGER PRIMARY KEY NOT NULL,
                            vorname VARCHAR(30),
                            zuname VARCHAR(40),
                            nachname VARCHAR(30),
                            anrede VARCHAR(20),
                            adresse VARCHAR(50),
                            plz VARCHAR(15),
                            ort VARCHAR(25),
                            land VARCHAR(30),
                            privatnummer VARCHAR(35),
                            privatfaxnummer VARCHAR(35),
                            mobilnummer VARCHAR(35),
                            bueronummer VARCHAR(35),
                            buerofaxnummer VARCHAR(35)
                        )'''

                    self.cur.execute(sql)
                    self.con.commit()
Scheint auch wunderbar zu funktionieren.

Greetz
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mittwoch 12. Juli 2006, 14:34

So... Neue Methode neues Problem:
getall()

Code: Alles auswählen

    def getall (self):
        '''Rückgabe von allen Kontakten des Telefonbuchs'''

        sql = '''SELECT
                    id,
                    vorname,
                    zuname,
                    nachname,
                    anrede,
                    adresse,
                    plz,
                    ort,
                    land,
                    privatnummer,
                    privatfaxnummer,
                    mobilnummer,
                    bueronummer,
                    buerofaxnummer
                FROM
                    addresses'''

        self.cur.execute(sql)

        adresses    = {}
        i           = 1
        while True:
            row = self.cur.fetchone()

            if row:
                adresses[i] = {'id': row['id'],
                               'vorname': row['vorname'],
                               'zuname': row['zuname'],
                               'nachname': row['nachname'],
                               'anrede': row['anrede'],
                               'adresse': row['adresse'],
                               'plz': row['plz'],
                               'ort': row['ort'],
                               'land': row['land'],
                               'privatnummer': row['privatnummer'],
                               'privatfaxnummer': row['privatfaxnummer'],
                               'mobilnummer': row['mobilnummer'],
                               'bueronummer': row['bueronummer'],
                               'buerofaxnummer': row['buerofaxnummer'],
                            }
                i = i+1
            else:
                return adresses

adr = Adress('./daten/address.sqldb')

adr.install()

adr.add('Max','Maximilian','Musterman','Herr','Musterstr 12',
'1234865','Musterstadt','Deutschland','004912326548','','01701234586','','')

adresses = adr.getall()
print adresses
Traceback (most recent call last):
File "Adressenverwaltung.py", line 225, in ?
main()
File "Adressenverwaltung.py", line 221, in main
adresses = adr.getall()
File "Adressenverwaltung.py", line 189, in getall
adresses = {'id': row['id'],
TypeError: tuple indices must be integers
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 12. Juli 2006, 14:34

CrackPod hat geschrieben:und wie kann man das mit älteren versionen überprüfen?
Hi CrackPod!

Indem man in der "sqlite_master"-Tabelle nachsieht.

http://www.sqlite.org/faq.html#q9

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten