Hallo zusammen,
ne absolute Anfängerfrage aber ich find dazu nix :
Ich lese per ADO-Recordset aus einer SQL-Server Datenbank diverse Felder. Alles klappt meiner Meinung..... Nur :
sumU = rsK.Fields("Umsatz").Value
einproz = sumU / 100
liefert die Fehlermeldung :
TypeError: unsupported operand type(s) for /: 'tuple' and 'int'
Das Feld "Umsatz" ist ein Float Wert in der Datenbank..... warum wird dies als "tuple" interpretiert???
Vielen Dank für eure Hilfe!!
Gruss
Markus
float + datenbank
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Weil ADO an der stelle eine Tupel zurückgibt, darum!macmark hat geschrieben:Das Feld "Umsatz" ist ein Float Wert in der Datenbank..... warum wird dies als "tuple" interpretiert???
Mach mal
Code: Alles auswählen
print sumU
Edit: Achja, nicht zu vergessen das obligatorische "Willkommen" Willkommen im Forum!
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
..... Darauf hätte ich nun nicht getippt!!! Aber Danke!!
Übrigens auch für das "Willkommen"
Hast du evtl. ne Website wo erklärt wird warum das so ist?? Zu "Python + ADO" in Google findet sich nix.
Gruss
Markus
Übrigens auch für das "Willkommen"
Hast du evtl. ne Website wo erklärt wird warum das so ist?? Zu "Python + ADO" in Google findet sich nix.
Gruss
Markus
"Humor ist der Knopf, der verhindert, dass einem der Kragen platzt"
... würde ich ja verstehen wenn ich im SQL-String mehrere Zahlen zurückbekommen würde..... aber es geht da nur um EINE Float Zahl !Buell hat geschrieben:... alle "Umsätze" als Tupel in sumU
"Humor ist der Knopf, der verhindert, dass einem der Kragen platzt"
stell dir die Datenbank vereinfacht als Tabelle vor:
Primärschlüssel | Umsatz | Spalte3 | Spalte 4| ...
diese Tabelle kann quasi unendlich viele Zeilen (Datensätze) enthalten. Mit:
erhälst du in einer Liste abgelegt alle Zeilen von Umsatz zB:
sumU = ['125.57','3415,23',...]
auch wenn du nur eine Zahl drin hast, liegt diese Zahl trotzdem in einer Liste, die in dem Fall nur ein Element enthält. Wie Leonidas schon richtig geschrieben hat, greifst du auf das 1. Element der Liste mit sumU[0] zu. Damit erhälst du dann die "Zahl" als float.
Also:
Primärschlüssel | Umsatz | Spalte3 | Spalte 4| ...
diese Tabelle kann quasi unendlich viele Zeilen (Datensätze) enthalten. Mit:
Code: Alles auswählen
sumU = rsK.Fields("Umsatz").Value
sumU = ['125.57','3415,23',...]
auch wenn du nur eine Zahl drin hast, liegt diese Zahl trotzdem in einer Liste, die in dem Fall nur ein Element enthält. Wie Leonidas schon richtig geschrieben hat, greifst du auf das 1. Element der Liste mit sumU[0] zu. Damit erhälst du dann die "Zahl" als float.
Also:
Code: Alles auswählen
sumU = rsK.Fields("Umsatz").Value
einproz = sumU[0] / 100.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Also ich habe das und das gefunden.macmark hat geschrieben:Hast du evtl. ne Website wo erklärt wird warum das so ist?? Zu "Python + ADO" in Google findet sich nix.
Warum da eine Tupel rauskommt kann ich dir auch nicht 100%ig sagen, das liegt einfach daran, wie die ADO-API ist.. die ist nunmal afair nicht PEP 249, dh. DB-API 2 kompatibel, so haben die Macher von ADO einfach entschieden (und auch mit der DB-API 2 wäre das so wie es ist, eine Liste oder Tupel). Warscheinlich meinten sie, dass jede SQL-Anweisung mehrere Werte ausgeben könnte, deswegen wäre es sinnvoller, an der Stelle einen Container (Tupel eben) auszugeben, in dem dann die eigentlichen Daten stecken.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Cool... Danke!!
Das Beispiel auf http://www.ecp.cc/ado_examples.shtml :
>>> y = r.Fields.Item(2).Value
>>> y
(0, 850000)
>>> z = y[1]/10000
>>> print 'this information costs $%.*f' % (2,z)
this information costs $85.00
... ist schon sehr vielsagend!!! Wenn man von VB auf Python umsteigt ist das recht gewöhnungsbedürftig.... ... aber trotzdem ne coole Sprache!
Das Beispiel auf http://www.ecp.cc/ado_examples.shtml :
>>> y = r.Fields.Item(2).Value
>>> y
(0, 850000)
>>> z = y[1]/10000
>>> print 'this information costs $%.*f' % (2,z)
this information costs $85.00
... ist schon sehr vielsagend!!! Wenn man von VB auf Python umsteigt ist das recht gewöhnungsbedürftig.... ... aber trotzdem ne coole Sprache!
"Humor ist der Knopf, der verhindert, dass einem der Kragen platzt"
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi @all!Leonidas hat geschrieben:Warscheinlich meinten sie, dass jede SQL-Anweisung mehrere Werte ausgeben könnte, deswegen wäre es sinnvoller, an der Stelle einen Container (Tupel eben) auszugeben, in dem dann die eigentlichen Daten stecken.
Ich bin überfragt, aber eines weiß ich gewiss. Die Anweisung
Code: Alles auswählen
rsK.Fields("Umsatz")
Code: Alles auswählen
rsK.Fields.Item("Umsatz").Value
Eventuell hilft es PyWin32 und ADO auf den neuesten Stand zu bringen.
Hier ein Test mit einer Artikeltabelle in einer MS SQL-Datenbank:
Code: Alles auswählen
>>> import win32com.client
>>> conn = win32com.client.Dispatch('ADODB.Connection')
>>> DSN = "Provider=SQLOLEDB.1;Password=IrgendeinPasswort;Persist Security Info=True;User ID=SWA;Initial Catalog=dbSWALokal;Data Source=(local)"
>>> conn.Open(DSN, "sa", "EinPasswort")
>>> rs = win32com.client.Dispatch('ADODB.Recordset')
>>> rs.Open("Select top 10 * from tArtikel", conn, 1, 3)
>>> print rs.Fields("ArtikelNr")
1
>>> print rs.Fields("ArtikelNr").Value
1
>>> print rs.Fields.Item("ArtikelNr").Value
1
>>> print rs.Fields.Item("ArtikelNr")
1
>>> rs.MoveNext()
>>> print rs.Fields.Item("ArtikelNr")
2
>>> print rs.Fields("VKP_Brutto")
0.0
>>> rs.Close()
>>> conn.Close()
>>>
@macmark: Das ist das normale Verhalten von ADO. Es stimmt also leider irgendetwas bei dir nicht.
lg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
.... mmmmhhh!! Sollte ich beides auf einem aktuellen Stand haben. PyWin32 habe ich erst vor 2 Wochen runtergeladen : pywin32-208.win32-py2.4 und ADO ist auch auf dem aktuellen Stand! Verwende auf meiner Dev-Maschine den SQL-Server 2005 Express.gerold hat geschrieben: Eventuell hilft es PyWin32 und ADO auf den neuesten Stand zu bringen.
@macmark: Das ist das normale Verhalten von ADO. Es stimmt also leider irgendetwas bei dir nicht.
Ich probiers mal auf anderen Maschinen..... vielleicht hängt es ja damit zusammen.
Poste auf jeden Fall das Ergebnis....
Gruss
Markus
"Humor ist der Knopf, der verhindert, dass einem der Kragen platzt"
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi Buell!Buell hat geschrieben:erhälst du in einer Liste abgelegt alle Zeilen von Umsatz zB:Code: Alles auswählen
sumU = rsK.Fields("Umsatz").Value
sumU = ['125.57','3415,23',...]
Leider muss ich dich da unterbrechen. ADO kennt einen Datensatzzeiger, der nach dem Ausführen einer SQL-Abfrage direkt auf dem ersten Datensatz liegt. Mit rs.MoveNext() wird der DS-Zeiger zum nächsten Datensatz verschoben.
Ist der DS-Zeiger auf der ersten Zeile, dann werden nur Werte der ersten Zeile zurück gegeben. Auf keinen Fall wird eine Liste aller Werte eines Feldes mit rs.Fields("Feldname") zurück gegeben. Was der Normalfall ist, sollte mein Beispiel im letzten Beitrag von mir ziemlich gut aufzeigen.
@macmark: Ein bischen mehr Code von dir würde uns den Fehler sicher schnell finden lassen.
lg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi Markus!macmark hat geschrieben:Verwende auf meiner Dev-Maschine den SQL-Server 2005 Express.
Alles was ich bis jetzt geschrieben habe, gilt bis zum SQL-Server 2000. Ob sich ADO beim SQL-Server 2005 Express anders verhält, das kann ich nicht sagen, da ich beim Umsteigen auf PostgreSQL bin und wahrscheinlich den Rest meines Lebens kein Bedarf mehr für den 2005er besteht.
Außerdem setze ich derzeit die ADO-Version 2.8 ein. Vielleicht verhält sich eine neuere Version anders.
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
ok..... hier grob der Code der derzeit klappt :
Edit (Leonidas): Code in Python-Tags gesetzt.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Tkinter import *
import sys
import win32com.client
root = Tk()
lblstatus=StringVar(root)
root.l=Label(root,textvariable=lblstatus)
root.l.pack()
DSN = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog="
DSN = DSN + "TestDB;Data Source=SQLEXPRESS;Use Procedure for Prepare=1"
DSN = DSN + ";Auto Translate=True;Packet Size=4096;Workstation ID="
DSN = DSN + "DEV;Use Encryption for Data=False;"
DSN = DSN + "Tag with column collation when possible=False"
lblstatus.set("DB öffnen .... ")
root.update()
monat = 1
monat = 2006
conn = win32com.client.Dispatch(r'ADODB.Connection')
conn.Open(DSN)
sumU = 0
sqlk = " SELECT Sum(Umsatz1)+Sum(Umsatz2)+Sum(Umsatz3) AS Umsatz "
sqlk = sqlk + " FROM tbStatistik "
sqlk = sqlk + " where month(Datum) = " + str(monat)
sqlk = sqlk + " and year(Datum) = " + str(jahr)
rsK = win32com.client.Dispatch(r'ADODB.Recordset')
rsK.Open(sqlk, conn, 1, 3)
if not rsK.eof:
sumU = rsK.Fields("Umsatz").Value[1] / 10000
rsK.Close()
einproz = sumU / 100
print einproz
print sumU
conn.Close()
lblstatus.set("Fertig .... ")
root.update()
"Humor ist der Knopf, der verhindert, dass einem der Kragen platzt"
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi macmark!macmark hat geschrieben:Code: Alles auswählen
sumU = rsK.Fields("Umsatz").Value[1] / 10000
Es lässt mir keine Ruhe -- Kann es wirklich sein, dass es von einer SQL-Server Version zur nächsten, so einen extremen Unterschied im Verhalten gibt?
Was kommt eigentlich als Ergebnis dieses Programmes raus? (Vielleicht musst du es noch anpassen, falls ich irgendwo noch einen Syntaxfehler drinnen habe.)
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import win32com.client
DSN = (
"Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;"
"Initial Catalog=TestDB;Data Source=SQLEXPRESS;Use Procedure for Prepare=1;"
"Auto Translate=True;Packet Size=4096;Workstation ID=DEV;"
"Use Encryption for Data=False;Tag with column collation when possible=False"
)
monat = 1
monat = 2006
conn = win32com.client.Dispatch(r'ADODB.Connection')
conn.Open(DSN)
rsK = win32com.client.Dispatch(r'ADODB.Recordset')
sqlk = \
"""SELECT
Sum(Umsatz1) as sum_umsatz1,
Sum(Umsatz2) as sum_umsatz2,
Sum(Umsatz3) as sum_umsatz3,
Sum(Umsatz1) + Sum(Umsatz2) + Sum(Umsatz3) AS sum_umsatz
FROM
tbStatistik
WHERE
(month(Datum) = %s) And
(year(Datum) = %s)
""" % (monat, jahr)
rsK.Open(sqlk, conn, 1, 3)
print "1: %s" % rsk.Fields("sum_umsatz1")
print "2: %s" % rsk.Fields("sum_umsatz2")
print "3: %s" % rsk.Fields("sum_umsatz3")
print "sum: %s" % rsk.Fields("sum_umsatz")
rsK.Close()
conn.Close()
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Hi Gerold,
das Thema hat mich nicht so ganz losgelassen und ich habe mit dem SQL-Server mal folgendes getestet :
Mit Testdaten versorgt kam folgendes dabei raus :
testdecimal: 12,34
testfloat: 14.56
testmoney: (0, 132000)
testnumeric: 14,4
testreal: 12.6000003815
testsmallmoney: (0, 608000)
D.h. nur bei einigen Datentypen reagiert wird das Ergebnis als Tuple zurückgegeben. Bei der mir vorliegenden Datenbank waren die Felder wirklich als Money definiert. In deiner Datenbank sind die wahrscheinlich anders definiert. Daher also der Unterschied.
Wer Lust hat kann das ja auch mal bei seiner DB simulieren ob sich Python/ADO da ähnlich verhält.
Schönen Gruss
Markus
das Thema hat mich nicht so ganz losgelassen und ich habe mit dem SQL-Server mal folgendes getestet :
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Tabelle im SQL-Server
#CREATE TABLE [testtab](
# [testdecimal] [decimal](18, 2) NULL,
# [testfloat] [float] NULL,
# [testmoney] [money] NULL,
# [testnum] [numeric](18, 2) NULL,
# [testreal] [real] NULL,
# [testsm] [smallmoney] NULL,
# [id] [int] NULL
#) ON [PRIMARY]
import win32com.client
DSN = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog="
DSN = DSN + "TestDB;Data Source=SQLEXPRESS"
conn = win32com.client.Dispatch(r'ADODB.Connection')
conn.Open(DSN)
sql = 'select id, testdecimal, testfloat, testmoney, testnum, testreal, testsm from testtab order by id '
rs = win32com.client.Dispatch(r'ADODB.Recordset')
rs.Open(sql, conn, 1, 3)
if not rs.eof:
print "testdecimal: %s" % rs.Fields("testdecimal")
print "testfloat: %s" % rs.Fields("testfloat")
print "testmoney: %s" % rs.Fields("testmoney")
print "testnumeric: %s" % rs.Fields("testnum")
print "testreal: %s" % rs.Fields("testreal")
print "testsmallmoney: %s" % rs.Fields("testsm")
rs.Close()
conn.Close()
testdecimal: 12,34
testfloat: 14.56
testmoney: (0, 132000)
testnumeric: 14,4
testreal: 12.6000003815
testsmallmoney: (0, 608000)
D.h. nur bei einigen Datentypen reagiert wird das Ergebnis als Tuple zurückgegeben. Bei der mir vorliegenden Datenbank waren die Felder wirklich als Money definiert. In deiner Datenbank sind die wahrscheinlich anders definiert. Daher also der Unterschied.
Wer Lust hat kann das ja auch mal bei seiner DB simulieren ob sich Python/ADO da ähnlich verhält.
Schönen Gruss
Markus
"Humor ist der Knopf, der verhindert, dass einem der Kragen platzt"