SQLite Abfrage

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

Hallo!
ich wollte mit folgenden code eine tabelle erstellen die id's x-y und für diese id ist in der db ein type zugeteit, zb grass oder stein, aber wenn cih abfrage, kommt immer nur das heraus:

Code: Alles auswählen

<td id="1-1" class="[]"></td>
hier der python:

Code: Alles auswählen

#!D:/Python33/python.exe
#print('#!/usr/bin/python')

import sqlite3

print("Content-type:text/html\r\n\r\n")

print('''
		<html>
			<head>
				<title>Terracraft</title>
				<link rel="stylesheet" type="text/css" href="style.css"/>
				<link href='http://fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
			</head>
			<body>
			</body>
		</html>
	''')

db = 'map.db'
connection = sqlite3.connect(db)
print('<span class="ok">Database: Connected</span> <span class="little">Connected to DB: ', db, '</span><br>')
cursor = connection.cursor()

cont = '<table>'
x = 0
y = 0
while y < 100:
	y += 1
	cont += '<tr>'
	while x < 100:
		x += 1
		v_id = '{}-{}'.format(x,y)
		sql = '''SELECT type FROM map WHERE id=''' + v_id
		try:
			cursor.execute(sql)
		except sqlite3.Error as e:
			print('<span class="err">Database: SQL Error</span> <span class="little">Error: ', e.args[0], '</span><br>')
		row = cursor.fetchall()
		cont += '<td id="{}" class="{}"></td>'.format(v_id, row)
	x = 0
	cont += '</tr>'
cont += '</table>'

print(cont)
Zuletzt geändert von Anonymous am Dienstag 24. September 2013, 15:27, insgesamt 1-mal geändert.
Grund: Quelltexte in Code-Tags gesetzt.
Sirius3
User
Beiträge: 18253
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo nitram0598,
erstens solltest Du keine SQL-Befehle zusammenstücken und zweitens wundert es mich, dass sqlite da dann keinen Fehler meldet:

Code: Alles auswählen

cursor.execute('SELECT type FROM map WHERE id=?',[v_id])
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

wunderte mich auch, aber es funzt immer noch nicht, code:

Code: Alles auswählen

while x < 100:
		x += 1
		v_id = '{}-{}'.format(x,y)
		sql = 'SELECT type FROM map WHERE id=?'
		try:
			cursor.execute(sql, [v_id])
		except sqlite3.Error as e:
			print('<span class="err">Database: SQL Error</span> <span class="little">Error: ', e.args[0], '</span><br>')
		row = cursor.fetchone()
		cont += '<td id="{}" class="{}"></td>'.format(v_id, row)
im borwser ausgabe:

Code: Alles auswählen

<td id="1-7" class="None"></td>
BlackJack

@nitram0598: Dann gibt es zu dem gegebenen Wert in der `id`-Spalte keinen Eintrag. Bist Du sicher, dass es dort etwas gibt? Und das Du die richtige DB-Datei verwendest?

Die ID ist auch ungewöhnlich. Das sind eigentlich Werte für zwei Spalten in einer zusammengemanscht und lässt sich dementsprechend schlecht abfragen. Denn eigentlich möchte man das auf zwei Spalten aufteilen und könnte dann *eine* Abfrage für *alle* Felder der Tabelle machen, statt für jedes Feld eine neue Abfrage zu starten.

Sonstige Anmerkungen: Die beiden ``while``-Schleifen sollten ``for``-Schleifen sein. Damit spart man sich die Initialisierung von `x` und `y` vor der Schleife, das erhöhen in der Schleife, und die Frage beim Leser wie sich `x` und `y` wohl verhalten.

Wiederholtes zusammensetzen von einer immer länger werdenden Zeichenkette durch ``+`` ist ineffizient. Da Zeichenketten in Python unveränderbar sind, wird bei jedem ``+`` eine neue Zeichenkette erstellt in die die Inhalte der beiden alten kopiert werden. Da werden unnötig Daten im Speicher umherkopiert. Idiomatisch wäre es die Teilzeichenketten in einer Liste zu sammeln und am Ende dann mit ``''.join(parts)`` zusammen zu setzen. Wobei die Vermischung von Datenbankabfrage und HTML zusammen bauen auch unschön ist. Das sollte man sauber trennen. Am besten auch ein Template-System wie Jinja2 verwenden.
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

wie funktionieren denn in python for schleifen, jedenfalls nicht so wie normaler weise...?
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

oder kannst du mich mal in skype adden und ich zeige dir dann dateien, dann können wir besser richtigstellen und das ergebnis lade ich dann hoch skype: marfi_98
BlackJack

@nitram0598: Ähm, wie kann man in einer Sprache programmieren von der man noch nicht einmal die Schleifenarten kennt? Vielleicht solltest Du erst einmal ein Grundlagentutorial durcharbeiten. In der Python-Dokumentation befindet sich eins das man auf jeden Fall mal durchgearbeitet haben sollte. Insbesondere wenn man merkt das man mit so etwas grundlegendem wie einer ``for``-Schleife nicht klar kommt, sollte das doch ein Hinweis sein, dass man besser noch nicht mit etwas deutlich komplexerem anfängt.
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

1. ich komme mit allem sehr gut klar, habe jezt von c++ zu python gewächselt, in c++ komme ich bestenz klar, ich bezeichne mich dort sogar als erfahrener, was ne for schleife ist weiß ich, blos in python funktioniert sie nicht so

in c++ oder php: for i; i <0, i++

aber in python???
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nitram0598 hat geschrieben:in c++ oder php: for i; i <0, i++

aber in python???
So wie es ziemlich weit vorne im Tutorial beim Thema "for Statements" steht.
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

danke, ich habe das range(x) völlig überlesen, sry^^

nun zurück zu dem problem, warum funktioniert es nicht? hier mal alle dateien:

mapcreator.py (insert-file): http://pastebin.com/pcLk2AGs

die index.py (select-file): http://pastebin.com/yi1jGAU2

das ergebnis: http://pastebin.com/08F0eJf3

wo ist der fehler? ;(
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nitram0598 hat geschrieben:wo ist der fehler? ;(
Ich kann dir auf die Schnelle nicht sagen wo der Fehler in deinem Code liegt. Ich kann dir aber direkt sagen - und damit das wiederholen was BlackJack schon erwähnt hat -, dass dein Datenbankdesign verkorkst ist.

Eine sprechende ID ist keine gute Idee. Du musst mit deinem Ansatz 10000 Anfragen an die Datenbank stellen. Das ist der helle Wahnsinn für so eine Aufgabe. Wenn deine Tabelle map Felder für x und y hätte, dann könntest du einfach "SELECT x, y, type FROM map WHERE x < 100 AND y < 100 ORDER BY x, y" verwenden. Das wäre eine einzige Anfrage und das eine zurückgelieferte Resultset mit 10000 Zeilen könntest du dann mit Python weiterverwursten.

Ehrlich, ich habe keine Lust in deinem aktuellen Code nach dem konkreten Fehler zu suchen weil er einfach auf einem falschen Datenmodell aufbaut. Ich beschäftige mich jetzt seit über 25 Jahren mit relationalen Datenbanken und das was du da im Moment machst tut mir beim Hinschauen einfach nur weh.
BlackJack

@nitram0598: Und nicht viel weiter unten steht zum Beispiel was ein ``else``-Zweig zu einer Schleife macht, was es so nicht in C++ und PHP gibt. Nur weil man schon ein paar Programmiersprachen gesehen hat, heisst das nicht, dass man eine neue einfach so lernen kann in dem man sich die Syntax-Konstrukte aus den alten Sprachen irgendwie 1:1 auf die neue Sprache umbastelt. Ein Sprache lernen heisst auch die dort verwendeten Sprachkonstrukte und Idiome zu lernen, und da muss man auch als erfahrener Programmierer mit den Grundlagentutorials anfangen. Sonst schreibst Du am Ende kein Python sondern C++ oder PHP in Python-Syntax gedrängt. Da stellt sich dann die Frage warum überhaupt Python.

Im `mapcreator` sehe ich nirgends einen `commit()`-Aufruf, also bleibt die Tabelle am Ende leer.

Auch wenn dort keine Benutzereingaben ins Spiel kommen, sollte man Werte grundsätzlich nicht selber in SQL-Anweisungen hinein formatieren, sondern dass dem Datenbankmodul überlassen.

Was bedeutet das `v_` bei `v_id`? Und muss man `error` wirklich mit `e` abkürzen?

Da anscheinend alles komplett in Deiner Hand liegt, also auch der DB-Entwurf, trenn um Himmels willen die beiden Werte der ID in eigenständige Spalten. Man macht sich das leben nur unnötig schwer wenn man verschiedene Werte zu einer Zeichenkette vermanscht.

Wenn man schon CGI-Skripte schreibt, sollte man das `cgitb`-Modul und da dann die `enable()`-Funktion irgendwo ganz weit oben im Skript verwenden, damit man beim entwickeln unerwartete Ausnahmen im Browser angezeigt bekommt.

Allerdings schreibt kein Mensch heute mehr CGI-Skripte. Verwende wenigstens eines der Mikrorahmenwerke wie Bottle oder Flask. CGI ist letztes Jahrtausend. Und man erfindet das Rad neu, was einem die Rahmenwerke alles schon bieten. Üblicherweise in besser und besser getestet.
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

also kann mir jemand nochmal genau sagen was ich ändern/bessern muss?
BlackJack

@nitram0598: Da stehen doch nun schon ein ganzer Haufen Verbesserungs- und Änderungsvorschläge. Ganz konkret ist die Datenbank leer weil `commit()` nicht aufgerufen wird. Schau mal die Beispiele in der Dokumentation an: http://docs.python.org/3/library/sqlite3.html

Du hättest übrigens auch mal mit der CLI von sqlite3 in die Datenbank schauen können, oder mit einem der diversen grafischen Werkzeuge für Sqlite3-Datenbanken. Dann wärst Du viel schneller darauf gekommen, dass es schon vor der Abfrage der Daten ein Problem gibt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

nitram0598 hat geschrieben:... in c++ komme ich bestenz klar, ich bezeichne mich dort sogar als erfahrener, ...
Nach Deiner bisherigen Leistung hier bezweifel ich das stark! Als erfahrener Programmierer - gleich welche Sprache man bisher beherrscht - sollte man es schon schaffen, solche grundlegenden Dinge *selbstsändig* über eine / die Dokumentation sowie den üblichen Suchmaschinen oder Quellen zu recherchieren.

Natürlich kann und sollte man auch Fragen stellen - denn wie BlackJack es schon anmerkte, sind alle Sprachen verschiedenen, mal mehr, mal weniger. Allerdings sollten das dann schon fundierte Fragen sein.

Alleine die genannten Verbesserungen zu ignorieren zeugt eher davon, dass Dir wenig in den Schoß fliegt und Du darüber hinaus zu wenig bereit bist, Dir grundlegendes, fehlendes Wissen anzueignen.

Dein Vorgehen an sich ist wenig idiomatisch; in Python (und eigentlich in jeder Sprache) programmiert man keine Webapp from scratch, sondern nutzt ein Framework. Ob Fullstack- oder Microframework muss dann zwar jeder für sich selbst entscheiden, aber komplett ohne anzufangen spricht dafür, dass Du noch keine Ahnung von der Materie hast (Sprach unabhängig!).

Schau Dir doch mal Django, Flask oder Bottle an. Mache Dich mit Templating-Mechanismen und ORMs (+ SQL-Abstraction-Layern) vertraut. Alles in einem findest Du bei Django; ansonsten musst Du separat gucken. Jinja2 wurde schon genannt, als ORM außerhalb von Django kommt eigentlich nur SQLALchemy in Frage.

Aber ehrlich gesagt: Wenn es an einer ``for``-Schleife hapert, würde ich *sämtliche* Web-Ansprüche erst einmal zurückstellen und mich auf den Kern der Sprache konzentrieren. Die Business-Logik kannst Du ja auch schon ohne Rahmenwerke, DB-Anbindung usw. erstellen und später - je nach Güte - zu einem Großteil wiederverwenden ;-)

Du wirst auf Deinem bisherigen Weg nicht glücklich mit Python werden :!:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

1. es hapert nicht an einer for schleife
2. von frameworks halte ich NIX
ich ahbe das prblem jetzt schon gelöst, danke trotzdem
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

nitram0598 hat geschrieben:1. es hapert nicht an einer for schleife
Offenbar wußtest Du weiter oben nicht, wie eine solche in Python funktioniert - da das *absolute Basics* sind, hapert es sehr wohl daran ;-)
nitram0598 hat geschrieben: 2. von frameworks halte ich NIX
Diese Einstellung solltest Du *dringend* überdenken.

Rein Interesse halber: Verwendest Du überhaupt "fremde" Libs oder schreibst Du alles selber? Wo ziehst Du die Grenze zwischen "mache ich selber" und "nutze etwas fertiges"?

Eigentlich unterscheidet sich ein Webframework nämlich nicht von anderen Bibliotheken oder auch Frameworks (Qt z.B. - in der C++-Welt sicherlich eines der mächtigsten überhaupt). Von daher verstehe ich die obige Aussage nicht... speziell von jemandem, der sich selber als "erfahren" bezeichnet!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

Zu 2. macht dann aber der Schritt von PHP zu Python Sinn, denn PHP ist ja im Grunde ein Framework für Webentwicklung. :-)

Mal ernsthaft, wenn Du mit Python-Webanwendungen entwickeln willst, dann musst Du ein Framework benutzen. Oder Du schreibst Dir selber eins — zwangsläufig. Mit all den Nachteilen die sich daraus ergeben.
nitram0598
User
Beiträge: 41
Registriert: Dienstag 24. September 2013, 14:53

so direkt meine ich das nicht, blos das ich zb arbeitersparende frameworks hasse
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

nitram0598 hat geschrieben:... blos das ich zb arbeitersparende frameworks hasse
Also bist Du Masochist und liebst Mehrarbeit? :twisted:

Komisch, meistens strebt der Mensch in all seinem Tun nach Arbeitserleichterungen... ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten