Hallo zusammen,
ich möchte mit Python 2.5 eine sqlite3-Tabelle anlegen. Sowohl der Tabellennamen als auch die Spaltennamen habe ich als Variablen verfügbar.
Ich weiss, das ich Einträge dann mittels des ?-Syntaxes machen kann, aber wie bekomm eich die Variablennamen beim anlegen einer Tabelle übergeben?
Danke
BastiL
DB-Anfänger - Tabelle mit Variablen anlegen in sqlite3
BastiL: Die '?' sind nur für Werte geeignet. Du wirst also hier einfach eine SQL-Anweisung zum Anlegen der Datenbank als Zeichenkette zusammen bauen müssen.
Oder Du verwendest z.B. SQLAlchemy als Abstraktionsschicht.
Allerdings solltest Du gut aufpassen was alles Böses passieren kann, wenn die Daten von "aussen" kommen und ungeprüft einfach so verwendet werden.
Oder Du verwendest z.B. SQLAlchemy als Abstraktionsschicht.
Allerdings solltest Du gut aufpassen was alles Böses passieren kann, wenn die Daten von "aussen" kommen und ungeprüft einfach so verwendet werden.
Code: Alles auswählen
def create_table(name, *columns):
return "create table %s (%s)" % (name, ", ".join(columns))
print create_table("t", "x", "y", "z")
Wundere dich übrigens nicht: SQLite legt die Spaltennamen nicht notwendigerweise in der Reihenfolge an, wie du sie definiert hast. Entsprechend sind SELECTs über das Kommandozeilentool äußerst bescheiden zu lesen, wenn etwa die Spalte `id` nicht als erste angezeigt wird, sondern mittendrin. Gemeinsam mit so Eigenheiten wie der Notwendigkeit, Tabellen neu anlegen zu müssen um Spalten entfernen zu können, habe ich SQLite dann auch recht bald den Rücken gekehrt.
Für den Fall, dass deine Tabellen- oder Spaltennamen mit reservierten Schlüsselwörtern kollidieren, lässt sich der Code von sma wie folgt mit zusätzlichen Anführungszeichen erweitern (Spalten wie `foo'bar` solltest du dennoch nicht anlegen ):
Für den Fall, dass deine Tabellen- oder Spaltennamen mit reservierten Schlüsselwörtern kollidieren, lässt sich der Code von sma wie folgt mit zusätzlichen Anführungszeichen erweitern (Spalten wie `foo'bar` solltest du dennoch nicht anlegen ):
Code: Alles auswählen
def create_table(name, *columns):
return "CREATE TABLE '%s' ('%s')" % (name, "', '".join(columns))
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Y0Gi!Y0Gi hat geschrieben:SQLite legt die Spaltennamen nicht notwendigerweise in der Reihenfolge an, wie du sie definiert hast.
Das habe ich bis jetzt noch nicht beobachten können. Vielleicht hattest du eine Abstraktionsschicht dazwischen, die das verbockt hat.
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.
Kann ich auch nicht bestägigen und hege auch den Verdacht, dass da irgendwo ein Python-Dictionary zwischengeschaltet war.
Hmmmm. Na gut, wenn ihr das sagt. Ich *kann* mir vorstellen, dass es eine alte Version von SQLAlchemy (< 0.5, evtl. < 0.4) gewesen sein *könnte*, weil die damals noch nicht die Reihenfolge berücksichtigt hat. Dann nehme ich hiermit alles zurück und behaupte das Gegenteil Die anderen Einschränkungen von SQLite sind allerdings noch vorhanden und manchmal recht nervig.
Ok, so weit klappt es schon mal - danke.
Jetzt möchte ich aber bevor ich die Spalten anlege prüfen, ob die schon da sind. Dazu gibt es so wie ich das sehe das "IF NOT EXIST" SQL-statement ab sqlite 3.3. Allerdings muss ich zu sqlite 3.2 kompatibel bleiben. Wie kann ich so etwas dann machen? Irgendwie kann man doch sicher die Spaltentitel abfragen und dann mit den Strings abgleichen, die ich in meinem Dictionary habe?
Etwas präziser möchte ich den Inhalt eines DIctionaries in der Datenbank ablegen. Der Schlüssel entspricht dem Spaltennamen, der angelegt werden soll falls es noch keine entsprechende Spalte gibt. Der Wert ist dann in der jeweiligen Spalte abzulegen.
Gruß
Jetzt möchte ich aber bevor ich die Spalten anlege prüfen, ob die schon da sind. Dazu gibt es so wie ich das sehe das "IF NOT EXIST" SQL-statement ab sqlite 3.3. Allerdings muss ich zu sqlite 3.2 kompatibel bleiben. Wie kann ich so etwas dann machen? Irgendwie kann man doch sicher die Spaltentitel abfragen und dann mit den Strings abgleichen, die ich in meinem Dictionary habe?
Etwas präziser möchte ich den Inhalt eines DIctionaries in der Datenbank ablegen. Der Schlüssel entspricht dem Spaltennamen, der angelegt werden soll falls es noch keine entsprechende Spalte gibt. Der Wert ist dann in der jeweiligen Spalte abzulegen.
Gruß
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Was weißt Du denn nicht? Was hast Du schon probiert? Poste doch mal nen Snippet!BastiL hat geschrieben:Ok, jetzt habe ich eine Liste mit Tupeln der Überschriften bekommen. JEtzt versuche ich das mit meinen Strings abzugleichen und bekomme das nicht hin. Ich weiss nicht wie ich mit dem Tupel arbeiten kann....
Mal so generell: Was schreibst Du da eigentlich? Soll das ne Art Editor für SQLite werden? Imho macht das Hinzufügen von Spalten nämlich in den wenigsten Fällen Sinn und ist eher Ausdruck für schlechtes DB-Design ...
Zuletzt geändert von Hyperion am Montag 8. Juni 2009, 19:29, insgesamt 1-mal geändert.
Nein bei weitem nicht. Ich schreibe ein Interface zu einem anderen Programm. Die Parameter der Schnittstelle sollen zusätzlich in einer Datenbank abgelegt werden. Ich dachte es ist sichere ich prüfe zunächst ob die Spalte da ist, bevor ich versuche da was reinzuschreiben.Hyperion hat geschrieben:Mal so generell: Was schreibst Du da eigentlich? Soll das ne Art Editor für SQLite werden? Imho macht das Hinzufügen von Spalten nämlich in den wenigsten Fällen Sinn und ist eher Ausdruck für schlechtes DB-Design ...
Die Parameter habe ich in Python-DIctionaries abgelegt und möchte Sie nun in einer sqlite-DB sichern. Bisher sieht das ganze etwa so aus:
Code: Alles auswählen
def createtable(self, tablename, columns):
__sql = "SELECT name FROM sqlite_master WHERE (type = 'table') and (name = '" + tablename + "')"
self.__cursor.execute(__sql)
__row = self.__cursor.fetchone()
if not __row:
# Die Tabelle existiert noch nicht. Sie kann erstellt werden.
__sql = """CREATE TABLE %s (%s)""" % (tablename, ", ".join(columns))
self.__cursor.execute(__sql)
# Alle existierenden Spaltennamen abfragen und in einer Liste sichern
__sql = """SELECT name FROM sqlite_master WHERE (type = 'index')"""
self.__cursor.execute(__sql)
__spalten = self.__cursor.fetchall()
# Abgleich der Spalten (wenn nicht bereits vorhanden...)
for __i in columns:
if not __i.split()[0] in __spalten:
print __i.split()[0], type(__spalten[0])
print "Spalte " + __i.split()[0] + " ist nicht in der Tabelle " + tablename + " vorhanden."
__sql = "CREATE INDEX " + __i.split()[0] + " ON " + tablename + " (" + __i.split()[0] + ")"
self.__cursor.execute(__sql)
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Das kapiere ich leider so immer noch nicht. Nutzt das andere Programm eine DB zum Ablegen / Auslesen der Daten? Wenn ja, dann ist die doch vorhanden und man kann davon ausgehen, dass das so ok ist!BastiL hat geschrieben: Nein bei weitem nicht. Ich schreibe ein Interface zu einem anderen Programm. Die Parameter der Schnittstelle sollen zusätzlich in einer Datenbank abgelegt werden. Ich dachte es ist sichere ich prüfe zunächst ob die Spalte da ist, bevor ich versuche da was reinzuschreiben.
Ich würde ja bei insert-Statements einfach dei Felder explizit angeben, in die man Werte schreiben möchte. Sollte ein Feld nicht vorhanden sein, sollte es zu einer Exception kommen, die man dann gut abfangen kann. Imho ist das ein sauberer und einfacher Weg - zumal Du bei Deinem Ansatz nicht einmal garantieren kannst, dass zwischenzeitlich niemand anders die Tabellenstruktur ändert (Stichwort Transaktion).
http://openbook.galileocomputing.de/pyt ... 9c385b9ec3Leonidas hat geschrieben:Python hat keine privaten Attribute und ``__`` steht ganz sicher nicht für "privat". Wer hat dir denn sowas erzählt?
Vielleicht verstehe ich das auch falsch?
So ist es im wesentlichen gedacht. Das Programm soll aber die Datenbank selbst verwalten und bei Bedarf (einmal im Jahr) eine neue Datenbank samt der dann nötigen Tabellen erzeugen.Hyperion hat geschrieben:Das kapiere ich leider so immer noch nicht. Nutzt das andere Programm eine DB zum Ablegen / Auslesen der Daten? Wenn ja, dann ist die doch vorhanden und man kann davon ausgehen, dass das so ok ist!.
Hmm also einfach die Abfrage weglassen und die exception abfangen?Hyperion hat geschrieben: Ich würde ja bei insert-Statements einfach dei Felder explizit angeben, in die man Werte schreiben möchte. Sollte ein Feld nicht vorhanden sein, sollte es zu einer Exception kommen, die man dann gut abfangen kann. Imho ist das ein sauberer und einfacher Weg - zumal Du bei Deinem Ansatz nicht einmal garantieren kannst, dass zwischenzeitlich niemand anders die Tabellenstruktur ändert (Stichwort Transaktion).