Ein kleines Beispiel für ODBC am Beispiel von MS Access.

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben: Aber leider funktioniert es nicht:
[...]
Hat jemand damit Erfahrung gesammelt?
Hi Jens!

Es sieht wohl so aus, als ob du einer der ersten bist, die von Python aus auf den 2005'er zugreifen möchten. Leider kann ich dich dabei nicht unterstützen. --> Seit Visual Studio .NET versuche ich von MS-Produkten los zu kommen. Es wird sich also wahrscheinlich nie ein 2005'er SQL-Server auf einen meiner Computer verirren.

Hier ein Auszug aus einem alten Skript, das noch mit ODBC auf den SQL-Server 2000 zugegriffen hat.

Code: Alles auswählen

connstr = \
    "DRIVER=SQL Server;"\
    "SERVER=%s;"\
    "DATABASE=%s;"\
    "UID=%s;"\
    "PWD=%s" % (sw3host, sw3database, sw3username, sw3password)

try:
    conn = odbc.odbc(connstr)
except:
    message = u"Fehler: Beim Öffnen der Globaldatenbank"
    write_message(message)
    return False
Für einfache Sachen ist ODBC immer noch besser als nichts.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Naja, es ist nich so, das ich jetzt unbedinngt den 2005'er nutzten will. Aber das ist die einzige kostenlose Variante von M$ :?

Also da muß ich nochmal ein wenig probieren...

EDIT1:
Also hab im Python Cookbook eine Anleitung gefunden mit dem Kommandozeilen Programm osql eine Verbindung aufzubauen. Ich denke das kann man nicht wirklich produktiv nutzten, aber zumindest kann ich damit nachschauen, ob eine Verbindung mit dem User und dem Passwort generell klappt:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os, dbi, odbc

dbconf = {
    "dbHost"            : '.\SQLEXPRESS',
    "dbDatabaseName"    : 'DatabaseName',
    "dbUserName"        : 'UserName',
    "dbPassword"        : 'Password',
}

# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/144183
osql_test = (
    "osql -S%s -d%s -U%s -P%s "
    """/w 8192 -Q"set nocount on select name from master..syslogins where name = 'sa'"""
) % (
    dbconf["dbHost"],
    dbconf["dbDatabaseName"],
    dbconf["dbUserName"],
    dbconf["dbPassword"],
)
print osql_test
lst = os.popen(osql_test).readlines()
try:
    if lst[2].strip() == 'sa':
        print "connection OK"
    else:
        print "connection failed!"
except IndexError:
    print "Could not connect"

print "-"*80

DSN_info = (
    "DRIVER=SQL Server;"
    "SERVER=%s;"
    "DATABASE=%s;"
    "UID=%s;"
    "PASSWORD=%s;"
) % (
    dbconf["dbHost"],
    dbconf["dbDatabaseName"],
    dbconf["dbUserName"],
    dbconf["dbPassword"],
)
print DSN_info
c = odbc.odbc(DSN_info)
Ausgaben:
osql -S.\SQLEXPRESS -dDatabaseName -UUserName -PPassword /w 8192 -Q"set nocount on select name from master..syslogins where name = 'sa'
connection OK
--------------------------------------------------------------------------------
DRIVER=SQL Server;SERVER=.\SQLEXPRESS;DATABASE=DatabaseName;UID=UserName;PASSWORD=Password;
Traceback (most recent call last):
File "MSSQL mini test.py", line 47, in ?
c = odbc.odbc(DSN_info)
dbi.operation-error: [Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for user 'UserName'. in LOGIN
Wie man sehen kann klappt eine connection eigentlich schon. Aber per odbc geht's einfach nicht... Leider sehe ich in den LOG-Dateien auch nicht mehr Informationen, warum das so ist :twisted:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ach guck mal einer an, über adodbapi geht's :shock:
Obwohl das auch nur conn=win32com.client.Dispatch('ADODB.Connection') macht, also win32 nutzt.

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: UTF-8 -*-

""" Test MSSQL connection using adodbapi
Links
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/144183
"""

import os, adodbapi

test_select_statement = "select name from master..syslogins where name = 'sa'"

dbconf = {
    "dbHost"            : '.\SQLEXPRESS',
    "dbDatabaseName"    : 'DatabaseName',
    "dbUserName"        : 'UserName',
    "dbPassword"        : 'Password',
}

osql_test = (
    "osql -S%s -d%s -U%s -P%s "
    """/w 8192 -Q"set nocount on %s"""
) % (
    dbconf["dbHost"],
    dbconf["dbDatabaseName"],
    dbconf["dbUserName"],
    dbconf["dbPassword"],
    test_select_statement,
)
print osql_test
lst = os.popen(osql_test).readlines()
try:
    if lst[2].strip() == 'sa':
        print "connection OK"
    else:
        print "connection failed!"
except IndexError:
    print "Could not connect"

print "-"*80

DSN_info = (
    "DRIVER=SQL Server;"
    "SERVER=%s;"
    "DATABASE=%s;"
    "UID=%s;"
    "PASSWORD=%s;"
) % (
    dbconf["dbHost"],
    dbconf["dbDatabaseName"],
    dbconf["dbUserName"],
    dbconf["dbPassword"],
)
print DSN_info
connection = adodbapi.connect(DSN_info)
cursor = connection.cursor()
cursor.execute(test_select_statement)
data = cursor.fetchall()
print "SQL select result:", data
if data[0][0] == "sa":
    print "connection OK"
else:
    print "connection failed!"
Ausgabe:
osql -S.\SQLEXPRESS -dDatabaseName -UUserName -PPassword /w 8192 -Q"set nocount on select name from master..syslogins where name = 'sa'
connection OK
--------------------------------------------------------------------------------
DRIVER=SQL Server;SERVER=.\SQLEXPRESS;DATABASE=DatabaseName;UID=UserName;PASSWORD=Password;
SQL select result: ((u'sa',),)
connection OK

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Naja, es ist nich so, das ich jetzt unbedinngt den 2005'er nutzten will. Aber das ist die einzige kostenlose Variante von M$
[...]

Code: Alles auswählen

"PASSWORD=%s;"
[...]
Wie man sehen kann klappt eine connection eigentlich schon. Aber per odbc geht's einfach nicht... Leider sehe ich in den LOG-Dateien auch nicht mehr Informationen, warum das so ist :twisted:
Hi Jens!

Für ODBC muss das "PWD" heißen... :-)

Es gibt doch so wunderbare Datenbanksysteme für klein und groß, die nicht MS-geschwängert sind. Dann wird einem nur noch .NET aufs Auge gedrückt. Usw. :roll:
Ein großer Fehler beim Programmieren von SW3 war, dass ich auf MS SQL-Server als Datenbanksystem gesetzt habe. Dieses Ding hebt den Preis des Datenbankservers einfach zu sehr in die Höhe. Du brauchst unbedingt einen Server (Win2000 oder Win2003), dann brauchst du den MS SQL-Server und die Clientlizenzen. Damit nicht genug. Möchtest du eine geklusterte Lösung, muss es schon der teurere SQL-Server sein.

Hätte ich von Anfang an auf PostgreSQL gesetzt, dann hätte ich ein Programm, das auch für mittlere Betriebe interessant wäre. Außerdem kommt immer wieder die Anfrage rein, ob wir den Datenbankserver nicht auch unter Linux laufen lassen können.

Leider habe ich beim Programmieren ziemlich viele SQL-Server-eigene Funktionen eingesetzt, so dass eine Umstellung recht schwer wird.

... das war einfach mal so aus dem Nähkästchen geplaudert. :D

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:

jens hat geschrieben:Ach guck mal einer an, über adodbapi geht's :shock:
Obwohl das auch nur conn=win32com.client.Dispatch('ADODB.Connection') macht, also win32 nutzt.
Hi Jens!

Wenn "adodbapi" das Meiste unterstützt, was mit ADODB funktioniert, dann ist das ja gar nicht mal so schlecht.

Die Verwendung von "client.Dispatch" bedeutet ja nur, dass es eine "lose" Verbindung zum ActiveX-Objekt "ADODB.Connection" aufbaut. Das ist zwar beim Initialisieren langsamer, nimmt aber im laufenden Betrieb nicht unbedingt viel an Geschwindigkeit weg.

Das ist wie unter "Visual Basic Script" die Verwendung von

Code: Alles auswählen

Dim objConn
Set objConn = CreateObject("ADODB.Connection")
Wenn alles was du brauchst mit ADODBAPI funktioniert, dann hast du sicher keine schlechte Wahl getroffen.
Alles was nicht über ADODBAPI funktioniert, geht ganz sicher direkt über ADODB. Was natürlich einfacher ist, wenn man so wie ich schon jahrelang mit Visual Basic und ADODB programmiert hat. :lol:

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Aha, nun geht beides! Ist ja total bescheuert, das es bei ADODB "PASSWORD=..." heißt und bei ODBC "PWD=..." :? Aber das blödste überhaupt, das man nirgendwo einen Hinweis bekommt, das die DSN-Syntax falsch ist :roll: (EDIT: Dazu hab ich eine nette Adresse gefunden: http://www.connectionstrings.com )

Was ich jetzt aber nicht ganz verstehe. Im "ODBC Datenquellen-Manager" muß ich eigentlich nicht's einstellen. Also ich kann alle "Benutzer-DSN", "System-DSN" und "Datei-DSN" löschen. Die braucht man überhaupt nicht. Ich dachte eigentlich dort müßte ich erstmal eine ODBC Quelle einrichten, auf die ich zugreife?!?!


Also ein Unterschied kann ich direkt sehen: ADODB liefert direkt unicode-Zeichen zurück, wohingegen es bei ODBC direkt konvertiert ist.

Der Zeitunterschied beim Connect ist schon deutlich messbar. Bei ADODB braucht er ca. 0.125sec und bei ODBC 0.06sec...

Leider hab ich mich bei MySQL mit dem DictCursor angefreunet. Kann einer der beiden Schnittstellen das auch??? Oder muß ich mir da selber was programmieren???


Also das ganze ich nur dafür gedacht, das PyLuid halt auch mit IIS + MSSQL läuft. Mein Hauptaugenmerk liegt allerdings klar auf Apache und MySQL ;) Nur ich möchte es zusätzlich unterstützen, da es Firmen gibt, die darauf total abfahren :roll: Fragt mich nicht warum 8)

EDIT:
Dumm ist auch das beide als paramstyle den qmark als "?" nutzten. Ich hab in Pylucid allerdings immer "%s" genutzt... Naja, das läßt sich aber vielleicht noch ganz gut anpassen...
Zuletzt geändert von jens am Donnerstag 24. November 2005, 10:52, insgesamt 1-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ach verdammt, ich merke gerade, das MSSQL z.B. kein AUTO_INCREMENT kennt. Bzw. heißt das bei denen irgendwas mit IDENTITY...
Hm!

Also ich möchte ganz gern, das ich PyLucid mit MySQL, SQLite und MSSQL läuft.

Ist es da vielleicht eine gute Strategie einfach nur SQL92 zu nutzten??? Oder ist das auch nicht der kleinste gemeinsamme Nenner??? Ich meine so super tolle neue Dinge wie VIEWS, Trigger ect. nutzte ich aus unwissenheit eh nicht :roll:

Kennst jemand eine gute SQL92 Referenz-Seite?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Ach verdammt, ich merke gerade, das MSSQL z.B. kein AUTO_INCREMENT kennt. Bzw. heißt das bei denen irgendwas mit IDENTITY...
[...]
Also ich möchte ganz gern, das ich PyLucid mit MySQL, SQLite und MSSQL läuft.
Ist es da vielleicht eine gute Strategie einfach nur SQL92 zu nutzten??? Oder ist das auch nicht der kleinste gemeinsamme Nenner??? Ich meine so super tolle neue Dinge wie VIEWS, Trigger ect. nutzte ich aus unwissenheit eh nicht
Hi Jens!

Und unter PostgreSQL funktioniert das mit den Auto-Increments auch noch ein wenig anders. :wink:

SQL92 ist nicht unbedingt der kleinste gemeinsame Nenner, da keine der oben genannten Datenbanken SQL92 *komplett* unterstützen. Jedes dieser Datenbanksysteme unterstützt einen Teil von SQL92 und ein Teil davon wurde von den Programmierern jeweils ein wenig anders interpretiert. Das fängt schon beim Erstellen von Tabellen an.

Aus meiner Sicht wäre es eher ein Feature, wenn dein PyLucid **KEINEN** zusätzlichen Datenbankserver braucht.
Und dafür eignet sich *SQLite* wahrscheinlich am besten. Was ich gelesen habe, sollte SQLite auch mit Datenbanken der Größe einiger hundert MB wunderbar klar kommen. Warum also nicht alles auf SQLite "beschränken"? SQLite läuft unter Windows und Linux komplett transparent. Einen ODBC-Treiber, damit auf die SQLite-Datenbank auch mit Excel, Access und Co. zugegriffen werden kann, gibt es auch. Es ist schnell und unterstützt, da bin ich mir ziemlich sicher, alles was du brauchst. Ich kann mir nicht vorstellen, dass der Content einer PyLucid-Site diesen Rahmen je sprengen wird.

Es gibt Programme, mit denen man SQLite-Abfragen oder auch Tabellen designen kann. Man muss also nicht alles per Hand coden. Es gibt auch schon ein "PHPSQLiteAdmin" mit dem du deine Datenbanken wie bei "PHPMyAdmin" über einen Browser verwalten kannst.

Wenn man *AutoCommit* ausschaltet, dann ist dieses Ding richtig schnell.

Wo sind die Nachteile?
- Man lernt beim Programmieren nicht so viel über andere Datenbanksysteme. :wink:

IMHO:
Wie ich schon anmerken ließ, sehe ich keinen Vorteil in der Unterstützung mehrerer Datenbanksysteme, wenn sowiso schon SQLite unterstützt wird. Datenbankunabhängig wird das System wohl nur dann, wenn du noch eine Abstraktionsschicht zwischen den Datenbanken und PyLucid einschiebst. Dadurch wird das System aber sicher nicht schneller.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Naja, ich hab ja mit MySQL angefangen... Meine versuche mal eben alles für SQLite kompatibel zu machen, schlugen recht schnell fehl...

Eigentlich hab ich schon eine Abstraktionsschicht in PyLucid selber. Alle SQL-Abfragen laufen über ein Modul. Wobei es auch von allen Modulen/Plugins möglich war direkt an den Cursor-Objekt ran zu gehen.

Außerdem mache ich reichlich gebrauch von meinem eigenen SQLwrapper. Das deckt ca. 90% aller SQL-Abfragen ab. Nur Sonderwünsche bauen sich selber einen SQL-Statement zusammen...

Vielleicht ist auch SQLObject eine Lösung, aber alles darauf umzustellen dürfte mehr Arbeit sein...

Ich Probiere erstmal ein wenig weiter, mal sehen, wie's läuft.

Gerade hab ich festgestellt, das es ein "SHOW FIELDS FROM ..." auch erstmal so nicht gibt. Es geht mit:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '...';
:roll:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ach, so einfach ist das alles ja nicht:

Code: Alles auswählen

command:INSERT INTO lucid_TestTable ( data1,data2 ) VALUES ( ?,? ); with parameters: ('Value A 1', 'Value A 2')
Mehrfache Recordsets sind bei einer Transaktion mit diesem Cursortyp nicht m\xf6glich. \xc4ndern Sie entweder den Cursortyp, f\xfchren Sie Commit f\xfcr die Transaktion aus, oder schlie\xdfen Sie eines der Recordsets.
Mit absließendem "COMMIT;" klappt es auch nicht... In wie fern kann ich bei adodbapi einen anderen Curortyp nutzen?!?!?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also das mit dem COMMIT war wohl quatsch... Das ist nur bei 'Transaction' notwendig...

Aber irgendwie kommt mir das alles komisch vor:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import cgitb;cgitb.enable()

print "Content-type: text/html; charset=utf-8\r\n"

import adodbapi as dbapi


DSN_info = (
    "DRIVER=SQL Server;"
    "SERVER=.\SQLEXPRESS;"
    "DATABASE=DatabaseName;"
    "UID=UserName;"
    "PASSWORD=Password;"
)


class test:
    def __init__( self ):
        print "<pre>"
        self.connect()
        self.make_test_table()
        self.select_all()

        self.insert_1()
        self.select_all()

        self.delete_1()
        self.select_all()

        self.delete_test_table()
        self.close()
        print "</pre>"

    def connect(self):
        print "connect:",
        print DSN_info

        try:
            self.connection = dbapi.connect(DSN_info)
            self.cursor = self.connection.cursor()
        except Exception, e:
            print "Error:", e
            sys.exit()
        else:
            print "Connection OK"

    def close(self):
        self.connection.close()
        print "\n\nConnection closed"

    def make_test_table(self):
        SQLcommand  = (
            "CREATE TABLE TestTable ("
            "id INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), "
            "data1 VARCHAR( 50 ) NOT NULL, "
            "data2 VARCHAR( 50 ) NOT NULL"
            ");"
        )

        self.execute(
            "Creat a temporary test table",
            SQLcommand
        )

    def delete_test_table(self):
        self.execute(
            "Delete temporary test table",
            "DROP TABLE TestTable;"
        )

    def insert_1(self):
        self.execute(
            "RAW INSERT without SQLescaping",
            "INSERT INTO TestTable (data1,data2) VALUES ('Value A 1', 'Value A 2');"
        )

    def select_all(self):
        result = self.fetchall(
            "SELECT all",
            "SELECT * FROM TestTable;"
        )
        print result

    def delete_1(self):
        self.execute(
            "RAW DELETE values",
            "DELETE FROM TestTable WHERE data1='Value A 1';"
        )

    def execute(self, comment, SQLcommand):
        print "\n\n%s:" % comment
        print "SQLcommand:", SQLcommand
        try:
            self.cursor.execute(SQLcommand)
        except Exception, e:
            print "Error:", e
        else:
            print "OK"

    def fetchall(self, comment, SQLcommand):
        print "\n\n%s:" % comment
        print "SQLcommand:", SQLcommand
        try:
            self.cursor.execute(SQLcommand)
            return self.cursor.fetchall()
        except Exception, e:
            print "Error:", e
        else:
            print "OK"



if __name__ == "__main__":
    test()
Ich lasse doch einfach nur ein paar SQL-Befehle ablaufen. Dennoch kommt es zu dem Fehler:
Mehrfache Recordsets sind bei einer Transaktion mit diesem Cursortyp nicht m\xf6glich. \xc4ndern Sie entweder den Cursortyp, f\xfchren Sie Commit f\xfcr die Transaktion aus, oder schlie\xdfen Sie eines der Recordsets.
Aber je nachdem welche Befehle ich ausführe kommt das mal früher oder später. Irgendwie sehe ich da keinen Zusammenhang :?

Etwas komisch ist es auch wenn ich mit CREATE TABLE und DROP TABLE rumspiele... Man kann CREATE TABLE immer wieder ausführen und es kommt zu keinem Fehler?!?!?

Kann es sein, das es da irgendie ein Cache Mechanismus gibt?!?!


EDIT: So, nun hab ich genau die gleiche Aktion mit ODBC gemacht und damit klappt alles einwandfrei!!! Also ist ADOBDAPI mist???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Also das mit dem COMMIT war wohl quatsch... Das ist nur bei 'Transaction' notwendig...
[...]
Ich lasse doch einfach nur ein paar SQL-Befehle ablaufen. Dennoch kommt es zu dem Fehler:
Mehrfache Recordsets sind bei einer Transaktion mit diesem Cursortyp nicht m\xf6glich. \xc4ndern Sie entweder den Cursortyp, f\xfchren Sie Commit f\xfcr die Transaktion aus, oder schlie\xdfen Sie eines der Recordsets.
Aber je nachdem welche Befehle ich ausführe kommt das mal früher oder später. Irgendwie sehe ich da keinen Zusammenhang :?

Etwas komisch ist es auch wenn ich mit CREATE TABLE und DROP TABLE rumspiele... Man kann CREATE TABLE immer wieder ausführen und es kommt zu keinem Fehler?!?!?
Kann es sein, das es da irgendie ein Cache Mechanismus gibt?!?!
Hi Jens!

So wie ich das sehe, ignorierst du die Transaktionen. Wahrscheinlich wird vor jeder Abfrage automatisch ein "Begin Transaction" ausgeführt. Was kein Problem ist, wenn du nur ein paar Daten abfragst, aber es ist definitiv ein Problem, wenn du etwas in der Datenbank veränderst. Du musst wahrscheinlich nach jeder SQL-Anweisung, die etwas in der Datenbank verändert, ein adodb.commit, db.commit oder cursor.commit oder etwas ähnliches ausführen. Erst dann ist die Transaktion abgeschlossen -- die Änderung akzeptiert.

Wenn du eine Tabelle erstellst und noch im gleichen Prozess, die Tabelle füllst und abfragst, dann könnte es sein, dass du den Inhalt der Tabelle auslesen kannst. Wartest du aber eine Sekunde und möchtest dann noch einmal den Inhalt der Tabelle abfragen, dann ist nichts mehr da, was du abfragen könntest. Die Änderung wurde ja nicht mit "Commit Transaction" oder einem anderen, an die Connection gebundenen Befehl, abgeschlossen.

SQLite z.B. hält sich auch daran, dass es Änderungen nur nach einem "Commit Transation" akzeptiert. Und AutoCommit sollte man sowiso nicht einschalten, da das Datenbanksystem dadurch hergebremst wird.

Dass man "Create Table" immer wieder ausführen kann, sehe ich als Indiz für meine Theorie an. Natürlich kann man immer wieder die gleiche Tabelle erstellen, wenn der Erstellvorgang niemals korrekt abgeschlossen wurde.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dann ist bei MySQLdb und ODBC immer AutoCommit eingeschaltet???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Dann ist bei MySQLdb und ODBC immer AutoCommit eingeschaltet???
Hi Jens!

Bei MySQL weiß ich gar nicht, ob es so etwas wie ein Transaktionsmanagement überhaupt gibt.

ODBC hält sich aus so etwas raus. Es leitet einfach nur die SQL-Anweisungen weiter.

Als Standard-Einstellung von MS-SQL steht "AutoCommit" auf "Ein". Wenn man trotzdem mit ADODBAPI ein Commit nachschicken muss, dann mischt sich ADODBAPI ein.

Tut es auch. Ich habe soeben im Quelltext von ADODBAPI nachgesehen.

Code: Alles auswählen

if self.supportsTransactions:
    self.adoConn.IsolationLevel=defaultIsolationLevel
    self.adoConn.BeginTrans() #Disables autocommit
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Danke für deine Hilfe!!!

Also ich hab es jetzt nochmal mit adodbapi probiert. Wenn ich immer ein connection.commit() mache, kommt es wieder zu einem Fehler:
Die Transaktion kann im Firehosemodus nicht gestartet werden

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben: Wenn ich immer ein connection.commit() mache, kommt es wieder zu einem Fehler:
Die Transaktion kann im Firehosemodus nicht gestartet werden
Hi Jens!

Den **Firehosemodus** kenne ich noch nicht, das muss in der 2005'er Version neu eingeführt worden sein. Die Fehlermeldung ist auf deutsch. Da es im ADODBAPI keine deutschen Fehlermeldungen gibt, muss diese direkt vom SQL-Server kommen. Da im ADODBAPI auch kein besonderer Modus ausgewählt wird, dürfte das jetzt der Standardmodus für ADODB-Abfragen sein.
Wie auch immer -- mehr habe ich dazu nicht beizutragen. Ich möchte mich ja von MS-Datenbanken zurück ziehen, weil ich keinen Mehrwert mehr in der Verwendung dieser Technologie sehe.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Na, also ich möchte auch kein MSSQL Experte werden... Nur, weil es ja eine Anbindung gibt die ja fast die selbe ist (Python DB-API) wäre es doch schade, wenn ich nicht auch MSSQL unterstützen würde ;) Zumal ich es im konkreten Fall auch brauche ;)

Ich möchte gern generell an der "portierbarkeit" zur SQL-DB arbeiten um MySQL, SQLite (interessant für eine Standalone-Probier-Variante) und MSSQL unterstützen zu können.

Naja, ich denke da werde doch für MSSQL doch auf ODBC setzten, weil das andere einfach zuviele Probleme macht. Schade eigentlich...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Unterstützt nicht auch SQLObject MSSQL?
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hm! Das tut es wohl:
Currently SQLObject supports MySQL via MySQLdb aka MySQL-python, PostgreSQL via psycopg, SQLite via PySQLite, Firebird via kinterbasdb, Sybase via Sybase, and MAX DB (also known as SAP DB) via sapdb, MSSQL Server via pymssql (+ FreeTDS) or ADODBAPI (Win32).
Allerdings müßte ich dann schon komplett auf SQLObject übersatteln... Aber das dürfte wesendlich mehr Arbeit sein... Auf langer sicht gesehen, ist SQLObject schon interessant, aber das muß ich mir halt nochmal näher anschauen.

Ich denke ich mach erstmal mit win32/ODBC weiter...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten