letzten Eintrag einer Datenbank auslesen(?!) SQLite!!

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Freitag 27. April 2007, 21:11

Hi,

zuerst die Methode um die es hier geht =>

Code: Alles auswählen

def computeWeightDifference(self):

		# connect to DATABASE
		connection = sqlite.connect("E:\Schule\Programmieren\WeightWatcher\WeightWatcher.db", isolation_level = None)

		# read last entered weight
		cursor = connection.cursor()
		lastentry = cursor.execute("SELECT weight FROM WeightWatcher ORDER BY id DESC LIMIT 1")
		print lastentry
ich möchte den letzten Eintrag in der Spalte "weight" auslesen um damit weiterarbeiten zu können, aber irgendwie funktioniert das nicht, da kommt sowas wie "sqlite3.Cursor object at 0x009ED4d0" Wie mache ich das richtig?

mfg
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 27. April 2007, 21:27

Du machst erst eine cursor.execute() und das Ergebnis bekommst du mit cursor.fetchall() (oder fetschone)...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Freitag 27. April 2007, 21:29

print lastentry.fetchall()

versuchs mal damit ;-)

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

Freitag 27. April 2007, 21:33

Hallo cyp++!

Nur mal so nebenbei gesagt:

"E:\Schule\Programmieren\WeightWatcher\WeightWatcher.db" ist der Pfad zu deiner Datenbank. "WeightWatcher.db" ist deine Datenbank.

"WeightWatcher" ist eine Tabelle. Du möchtest also auf den letzten Datensatz der Tabelle "WeightWatcher" zugreifen.

Es ist eine gute Idee, die Tabellennamen klein, ohne Leer- oder Sonderzeichen zu schreiben und der Tabelle einen Namen zu verpassen, der aussagt was in der Tabelle zu finden ist. Da in deiner Tabelle sicher keine "WeightWatcher" zu finden sind ;-) würde ich als Namen z.B. "weight" oder "weights" vorschlagen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 29. April 2007, 13:30

lastentry.fetchone()[0]
gibt mir den letzten Wert zurück- alles richtig soweit! doch nach
type(lastentry.fetchone()[0])
bekomme ich 'unicode' zurück und damit kann ich nicht arbeiten, mit int() kann ich das komischerweise auch nicht umwandeln :( Wer kann mir helfen?
BlackJack

Sonntag 29. April 2007, 14:23

Das kann nicht sein:

Code: Alles auswählen

In [16]: a = u'42'

In [17]: type(a)
Out[17]: <type 'unicode'>

In [18]: int(a)
Out[18]: 42
Also was steht denn nun genau in der Datenbank?
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 29. April 2007, 14:49

kann es sein, dass fetchone() sich immer die stelle merkt wo es zuletzt war und dann da weitermacht, so wie read() ?
BlackJack

Sonntag 29. April 2007, 15:15

Natürlich, sonst könnte man es ja nicht in einer Schleife benutzen.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 29. April 2007, 15:19

das klärt natürlich so einiges..da ich in

Code: Alles auswählen

self.difference = int(lastentry.fetchone()[0])/100 * int(lastentry.fetchone())[0]-int(self.weight)
gleich 2x darauf zugreife.. wie könnte ich es realisieren? Das erklärt auch warum da ein None zurückkommt beim 2. Ausdruck.. und NoneType kann man natürlich nicht in ein integer umwandeln.
BlackJack

Sonntag 29. April 2007, 16:06

Der offensichtlich einfachste Weg wäre es, das Ergebnis an einen Namen zu binden und den in der Rechnung zu verwenden.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 29. April 2007, 17:31

Code: Alles auswählen

# WeightWatcher.py

import time
try:
    from pysqlite2 import dbapi2 as sqlite
except:
    from sqlite3 import dbapi2 as sqlite

class WeightWatcher(object):

	def __init__(self, weight):

		self.weight = weight

		self.difference = None
		self.date = None

	def writeIntoDatabase(self):

		# date
		self.date = str(time.localtime()[2]) + "." + str(time.localtime()[1]) + "." + str(time.localtime()[0])

		try:
			# connect to DATABASE
			connection = sqlite.connect("E:\Schule\Programmieren\WeightWatcher\WeightWatcher.db", isolation_level = None)

			# write into DATABASE
			cursor = connection.cursor()
			cursorparam = """INSERT INTO WeightWatcher VALUES(NULL, "%s", "%s", "%s")""" % (self.date, self.weight, self.difference)
			cursor.execute(cursorparam)
		except:
			print "Error"


	def computeWeightDifference(self):

		try:
			# connect to DATABASE
			connection = sqlite.connect("E:\Schule\Programmieren\WeightWatcher\WeightWatcher.db", isolation_level = None)

			# read last entered weight
			cursor = connection.cursor()
			lastentry = cursor.execute("SELECT weight FROM WeightWatcher ORDER BY id DESC LIMIT 1")

			try:
				ff = int(lastentry.fetchone()[0])
				self.difference = (float(ff/100)) * (ff-int(self.weight))
			except TypeError:
				ff = 0
			print self.difference
		except:
			print "Error!"

	def createDatabase(self):

		try:
			# create DATABASE
			connection = sqlite.connect("E:\Schule\Programmieren\WeightWatcher\WeightWatcher.db", isolation_level = None)

			# create TABLE
			cursor = connection.cursor()
			cursor.execute("""CREATE TABLE WeightWatcher(id integer primary key,date char(8),weight varchar(10),difference char(4))""")
		except:
			print "Error!"


weight = raw_input("Enter your today's weight")

weightwatcher = WeightWatcher(weight)
#weightwatcher.createDatabase()
weightwatcher.computeWeightDifference()
weightwatcher.writeIntoDatabase()




self.difference ist immer nun immer 0.0, weiß jemand wieso?
BlackJack

Sonntag 29. April 2007, 18:20

Integerarithmetik:

Code: Alles auswählen

In [24]: 50 / 100
Out[24]: 0
Wenn beide Zahlen ganze Zahlen sind, dann ist auch das Ergbnis der Division eine ganze Zahl.

Das Datum kann man übrigens einfacher als Zeichenkette erhalten:

Code: Alles auswählen

In [25]: time.strftime('%d.%m.%Y')
Out[25]: '29.04.2007'
Edit: Sag mal Dir ist schon klar, dass man in SQL-Datenbanken nicht nur Zeichenketten stecken kann, insbesondere wenn die Daten eigentlich Zahlen und Daten sind!? Was auch den Vorteil hätte, das die Daten dann auch als Zahlen wieder aus der Datenbank herauskommen.
cyp++
User
Beiträge: 69
Registriert: Freitag 22. September 2006, 13:54

Sonntag 29. April 2007, 18:54

gibt es in SQL denn float?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Sonntag 29. April 2007, 19:42

cyp++ hat geschrieben:gibt es in SQL denn float?
Hi cyp++!

http://docs.python.org/lib/node346.html

Hier hast du mal einen Prototypen, der auch mit Timestamps klar kommt.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

try:
    import sqlite3
except ImportError:
    from pysqlite2 import dbapi2 as sqlite3
import datetime

# Connection so erstellen, dass DATE- und TIMESTAMP-Felder erkannt werden.
conn = sqlite3.connect(
    ":memory:",
    detect_types = sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES
)

# weights-Tabelle erstellen
sql = """
CREATE TABLE weights (
    id INTEGER PRIMARY KEY,
    timestamp TIMESTAMP,
    weight REAL
)
"""
conn.execute(sql)
conn.commit()

# Index mit dem Feld timestamp erstellen
sql = """
CREATE INDEX ix_weights_timestamp 
ON weights (timestamp)
"""
conn.execute(sql)
conn.commit()

# Einen Datensatz in die Tabelle weights schreiben
sql = """
INSERT INTO weights (timestamp, weight) VALUES (?, ?)
"""
conn.execute(
    sql, (datetime.datetime.now(), 100)
)
conn.commit()

# Zwei Datensätze in die Tabelle weights schreiben
conn.executemany(
    sql, (
        (datetime.datetime.now(), 90),
        (datetime.datetime.now(), 80),
    )
)

# Alle Datensätze der Tabelle weights auslesen
sql = """
SELECT * FROM weights
"""
cur = conn.cursor()
cur.execute(sql)

for row in cur:
    print row # --> (1, datetime.datetime(2007, 4, 29, 20, 33, 47, 781000), 100.0)

Code: Alles auswählen

(1, datetime.datetime(2007, 4, 29, 22, 57, 24, 781000), 100.0)
(2, datetime.datetime(2007, 4, 29, 22, 57, 24, 781000), 90.0)
(3, datetime.datetime(2007, 4, 29, 22, 57, 24, 781000), 80.0)
mfg
Gerold
:-)
Zuletzt geändert von gerold am Sonntag 29. April 2007, 21:57, insgesamt 1-mal geändert.
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:

Sonntag 29. April 2007, 21:56

...Fortsetzung:

Code: Alles auswählen

# Letzten Datensatz der Tabelle weights auslesen
sql = """
SELECT id, timestamp, weight FROM weights ORDER BY id DESC LIMIT 1
"""
cur = conn.cursor()
cur.execute(sql)

id, timestamp, weight = cur.fetchone()

print "id:", id
print "timestamp:", timestamp
print "irgendeine Rechnung mit weight:", weight / 100

Code: Alles auswählen

id: 3
timestamp: 2007-04-29 22:56:19.765000
irgendeine Rechnung mit weight: 0.8
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten