Access Datenbanken

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

stigi hat geschrieben:

Code: Alles auswählen

UPDATE REGEL20 SET PA_INFO = 'Runden' WHERE REGEL20.PA_INFO <> TEXTE.TEX_AUSGABE
 and REGEL20.PA_INFO_TEXTNR = TEXTE.TEX_NUMMER and TEXTE.TEX_SPRACHE='deu'
Hi stigi!

Wenn du diese SQL-Anweisung in eine Access-Abfrage kopierst und dann ausführst -- was sagt Access dann dazu?

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
stigi
User
Beiträge: 64
Registriert: Dienstag 4. April 2006, 07:05

kann ich die abfrage in access irgendwo 1:1 hinkopieren oder muss ich mir das über den assistenten oder die entwurfsansicht zusammen stückeln ?

edit: schon gefunden ;) ich poste gleich das ergebnis
[img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img] read between the lines for better smelling socks [img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

stigi hat geschrieben:kann ich die abfrage in access irgendwo 1:1 hinkopieren oder muss ich mir das über den assistenten oder die entwurfsansicht zusammen stückeln ?
Hi stigi!

Neue Abfrage in der Entwurfsansicht --> Fenster "Tabelle anzeigen" schließen ohne neue Tabelle hinzuzufügen --> Menü: Ansicht --> SQL-Ansicht.

Menü: Abfrage --> Ausführen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
stigi
User
Beiträge: 64
Registriert: Dienstag 4. April 2006, 07:05

also im access funktioniert das query ohne Probleme. Access frägt mich nach 3 Werten:

nach TEXTE.TEX_AUSGABE - da geb ich dann das original ein 'Runden'
nach TEXTE.TEX_NUMMER - da geb ich die referenznummer 63308 ein
und nach TEXTE.TEX_SPRACHE - da geb ich dann 'deu' ein

damit wird genau dieses eine Feld welches ich korrigieren möchte korrekt verändert.

was nun? dann is was an meinem script falsch oder?

ahja danke für die access hilfe, hatte es grad selbst gefunden ;)

hier die ausgabe wenn ich es im script ausführe:

Code: Alles auswählen

Y:\Mitarbeiter\heilemannpa\pythonwin>spe6
Runddden
63308
Runden

Traceback (most recent call last):
  File "Y:\Mitarbeiter\...\pythonwin\spe6.py", line 20, in ?
    curForUpdate.execute(sql2)
dbi.program-error: [Microsoft][ODBC Microsoft Access Driver] 3 Parameter wurden
erwartet, aber es wurden zu wenig Parameter ³bergeben. in EXEC
[img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img] read between the lines for better smelling socks [img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

stigi hat geschrieben:also im access funktioniert das query ohne Probleme. Access frägt mich nach 3 Werten:

nach TEXTE.TEX_AUSGABE - da geb ich dann das original ein 'Runden'
nach TEXTE.TEX_NUMMER - da geb ich die referenznummer 63308 ein
und nach TEXTE.TEX_SPRACHE - da geb ich dann 'deu' ein
Hi stigi!

Da haben wir ja schon das Problem. Access fragt dich immer nur dann nach Parametern, wenn es einen Ausdruck nicht kennt. "TEXTE.TEX_AUSGABE" ist so ein Ausdruck. Woher soll Access denn wissen, dass du damit ein Tabellenfeld meinst? Du hast in der SQL-Anweisung ja kein "FROM" mit drinnen, das dem Access mitteilen würde, welche Tabellen erwartet werden. Ob dieses Feature (mit mehreren Tabellen) von Access überhaupt unterstützt wird, dass weiß ich auch nicht. Das müsste man ausprobieren oder nachschlagen.

Aber um die ganze Sache nicht zu kompliziert werden zu lassen --> hier die einfache Lösung:

Finde in der ersten SQL-Anweisung alle notwenigen Werte heraus und verwende die Werte, nicht die Felder, in der zweiten SQL-Anweisung.

So auf diese Art:

Code: Alles auswählen

sql = """
SELECT 
    id, vorname, nachname 
FROM 
    adressen 
WHERE
    (id = 1)
"""
cur.execute(sql)
id, vorname, nachname = cur.fetchone()

sql = """
UPDATE andere_tabelle
SET
    vorname = '%(vorname)s',
    nachname = '%(nachname)s'
WHERE
    (id = %(id)s)
""" % {
    "id": id,
    "vorname": vorname,
    "nachname": nachname
}
cur.execute(sql)
Dieser Code soll nur verdeutlichen, wie ich das meine.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
stigi
User
Beiträge: 64
Registriert: Dienstag 4. April 2006, 07:05

jippi funktioniert ;)

habs durch klammersetzung hinbekommen ihm zu sagen, dass es sich um ein Tabellenfeld handelt :) und wenn ich ihm beim UPDATE beiden Tabellen mitgeb, weis er auch was zu tun ist :)

Code: Alles auswählen

sql2 = ("UPDATE REGEL20, TEXTE SET REGEL20.PA_INFO = '%s'WHERE ((REGEL20.PA_INFO<>TEXTE.TEX_AUSGABE And REGEL20.PA_INFO_TEXTNR=TEXTE.TEX_NUMMER And TEXTE.TEX_SPRACHE='deu'));" %(string3))
curForUpdate.execute(sql2) 
jetzt kann ich weiterarbeiten :)
[img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img] read between the lines for better smelling socks [img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img]
stigi
User
Beiträge: 64
Registriert: Dienstag 4. April 2006, 07:05

sodele, jetzt hab ich auch schon das nächste Problem. Und zwar:

Ist es im SQL möglich die Abfragen case-sensitive zu gestalten? also wenn ich zwei felder mit dem Inhalt "Runden" und "runden" vergleich, sollen die als ungleich gelten, bisher sagt SQL leider, dass sie identisch sind.


edit:schon hinbekommen :lol:
edit2:das geht leider nur für den ersten Buchstaben des strings, muss aber für alle gehen, brauche also doch hilfe :(
[img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img] read between the lines for better smelling socks [img]http://img73.imageshack.us/img73/9951/stigismiley9cp.gif[/img]
Aquerias
User
Beiträge: 28
Registriert: Freitag 28. September 2007, 10:33

Hallo,

ich bin neu hier und habe ein Problem.
Genau wie Stigi möchte ich mit Python auf eine Access (2007) Datenbank zugreifen. Allerdings habe ich schon einige Vorschläge ausprobiert und meinen Fehler noch nicht gefunden.

Mein Python Code bisher:

>>> import dbi
>>> import odbc
>>> try:
... s = odbc.odbc('DRIVER=(Microsoft Access Driver (*.accdb));UID=admin;DBQ=C:\\Test.accdb')

Die Fehlermeldung:

Traceback (most recent call last):
File "<interactive input>", line 2, in ?
dbi.operation-error: [Microsoft][ODBC Driver Manager] Der Datenquellenname wurde nicht gefunden, und es wurde kein Standardtreiber angegeben in LOGIN

Es scheint so, dass ich irgendetwas vergessen habe.
Muss ich unter START\Systemsteuerung\Verwaltung\Datenquellen (ODBC)
noch etwas konfigurieren?

Gruß und schon mal Danke

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

Aquerias hat geschrieben:s = odbc.odbc('DRIVER=(Microsoft Access Driver (*.accdb));UID=admin;DBQ=C:\\Test.accdb')
Hallo Aquerias!

Willkommen im Python-Forum!

Verwende pyodbc http://pyodbc.sourceforge.net/. Das funktioniert besser als die dbi-Variante.

Code: Alles auswählen

conn = pyodbc.connect("DRIVER=Microsoft Access Driver (*.mdb);UID=admin;DBQ=C:\\Test.accdb")
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Aquerias
User
Beiträge: 28
Registriert: Freitag 28. September 2007, 10:33

Hallo Gerold,

danke für die schnelle Antwort.
Ich glaube es hat funktioniert. Die Fehlermeldung erscheint nicht mehr.
Allerdings fehlen mir wohl noch ein paar Grundlagen z.B. weiß ich nicht
für was .cursor() da ist.

Kennst Du ein gutes deutschsprachiges Tutorial, dass einem zeigt wie man
mit Python Daten aus Access abfragt?

Gru0

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

Aquerias hat geschrieben: Allerdings fehlen mir wohl noch ein paar Grundlagen z.B. weiß ich nicht für was .cursor() da ist.
Hallo Aquerias!

http://www.python-forum.de/topic-11615.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Aquerias
User
Beiträge: 28
Registriert: Freitag 28. September 2007, 10:33

Hallo,

ich habe Deine Anleitung durchgelesen und versucht einiges davon anzuwenden.

Mein Quellcode sieht bisher so aus:

>>> import pyodbc
>>> conn = pyodbc.connect("DRIVER=Microsoft Access Driver (*.mdb);UID=admin;DBQ=C:\\Test.mdb")
>>> def select_countries(conn):
... sql="""
... SELECT ContinentID, CountryCode, CountryNameDE
... FROM Countries
... ORDER BY ID
... """
...
>>> cur=conn.cursor()
>>> cur.execute(select_countries)

Danach bekomme ich folgende Fehlermeldung:

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: The first argument to execute must be a string or unicode query.


Was genau mache ich falsch?
Bezieht sich "The first argument" auf den Inhalt meiner Tabelle?


Ich hoffe mir kann jemand helfen.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo Aquerias!

Du hast dich nur verschrieben:

Code: Alles auswählen

cur.execute(sql) 
mfg
Gerold
:-)

PS: http://www.python-forum.de/faq.php#21
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Aquerias
User
Beiträge: 28
Registriert: Freitag 28. September 2007, 10:33

Danke für die Antwort,

leider bekomme ich trotzdem eine Fehlermeldung.

Code

Code: Alles auswählen

>>> import pyodbc
>>> conn = pyodbc.connect("DRIVER=Microsoft Access Driver (*.mdb);UID=admin;DBQ=C:\\Test.mdb")
>>> def select_countries(conn):
... 	sql="""
... 	SELECT ContinentID, CountryCode, CountryNameDE
... 	FROM Countries
... 	ORDER BY ID
... 	"""
... 
>>> cur=conn.cursor()
>>> cur.execute(sql)
Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
NameError: name 'sql' is not defined
Muss ich nicht die Funktion "select_countries" aufrufen, damit cur.execute weis was er holen soll?

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

Aquerias hat geschrieben:leider bekomme ich trotzdem eine Fehlermeldung.
Hallo Aquerias!

Die Zeilen 10 und 11 müssen ebenfalls eingerückt werden.

Das sind Schlampigkeitsfehler.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Aquerias
User
Beiträge: 28
Registriert: Freitag 28. September 2007, 10:33

Vielen Dank für die Tipps,

hat gut funktioniert.

Quellcode:

Code: Alles auswählen

>>> import pyodbc
>>> conn = pyodbc.connect("DRIVER=Microsoft Access Driver (*.mdb);UID=admin;DBQ=C:\\Test.mdb")
>>> def select_countries(conn):
... 	sql = """
... 	SELECT ID, ContinentID, CountryCode, CountryNameDE, CountryNameEN, Important
... 	FROM Countries
... 	"""
... 	cur = conn.cursor()
... 	cur.execute(sql)
... 	return cur
... 
>>> coun_cursor = select_countries(conn)
>>> for row in coun_cursor:
... 	print row.ID, row.ContinentID, row.CountryCode, row.CountryNameDE, row.CountryNameEN, row.Important
... 
>>> conn.close()
Nun werde ich versuchen die erhaltenen Infos in eine XML-Datei zu speichern. So wie ich gesehen habe ist dieser "ElementTree" recht nützlich.

Danke nochmals.

Aquerias
Aquerias
User
Beiträge: 28
Registriert: Freitag 28. September 2007, 10:33

Hallo,

nachdem das verbinden mit der Datenbank und das exportieren der Daten so gut funktioniert, wollte ich auch den umgekehrten Weg testen. Also mit Python auf die Datenbank zugreifen und Tabellen Einträge ändern. Nach einiger Sucherei im Internet bin ich auf folgenden Code gestoßen:

Code: Alles auswählen

>>> import sys, string, os, random, win32com.client
>>> conn = win32com.client.Dispatch(r'ADODB.Connection')
>>> DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:\\Test.mdb;'
>>> sql = "UPDATE Tab1 SET Tab1.Spalte1 = 20 WHERE (((Tab1.Spalte2)=118) AND ((Tab1.Spalte3)=50))"
>>> conn.Open(DSN)
>>> conn.Execute(sql)
(<COMObject Execute>, 3)
>>> conn.Close()

Das ganze funktioniert wunderbar. Ich habe für den Datenexport aus Access allerdings pyodbc verwendet.

Meine Frage: Was ist der unterschied zwischen pyodbc und win32com? Gibt es überhaupt einen? Wie würde der Code mit pyodbc aussehen?

Gruß

Aquerias
Antworten