Seite 1 von 1
Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 08:54
von NewPython19
Hallo
Ist es mit Sqlite3 in Python möglich, ein Datenfeld einer Datenbank über eine Schleife zu befüllen?
Ich möchte zum Beispiel in ein bestimmtes Datenfeld meines Datensatzen für jeden Datensatz in meiner Datenbank einen Wert eintragen.
Zu Beginn möchte ich im ersten Feld eine 1, im zweiten Feld eine 2 usw. stehen haben.
Ist das möglich?
Bisher habe ich mir folgendes überlegt (Ich weiß, dass ist nicht korrekt aber sowas in der Art stelle ich mir vor):
Code: Alles auswählen
os.chdir(directory)
connection = sqlite3.connect(database)
cursor = connection.cursor()
for row in cursor:
sqlClientID = """INSERT INTO Data(Number) VALUES (i) """
cursor.execute(sqlClientID)
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 09:03
von Sirius3
@NewPython19: warum sollte sqlite3 magisch as `i` im String durch eine Zahl, `Number` aber nicht ersetzen?
Statt dessen gibt es dafür Platzhalter:
Code: Alles auswählen
cursor.execute("INSERT INTO Data(Number) VALUES (?)", [i])
Der Code macht so keinen Sinn, `i` ist gar nicht definiert, `cursor` hat nichts, worüber er iterieren könnte, die Einrückungen sind falsch und `os.chdir` sollte in einem sauberen Programm nicht vorkommen. Pfade gibt man entweder relativ zum Arbeitsverzeichnis an, oder absolut.
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 09:11
von __blackjack__
@NewPython19: Möchtest Du neue Datensätze erstellen oder bestehende verändern? Der Code scheint ja über ein Abfrageergebnis zu itererieren, aber da fehlt die SQL-Anweisung für die Abfrage. Und innerhalb der Schleife werden dann versucht Datensätze zu erstellen.
Der Name für das SQL-Fragment ist `sqlClientID` – was ist das für eine ID? IDs für Fremdschlüssel lässt man in der Regel die Datenbank selbst erzeugen. Selbst wenn man in den Daten IDs von ”aussen” hat, verwenden Viele trotzdem zusätzlich eine künstliche ID als Primärschlüssel.
Das `i` in dem SQL sollte ein Platzhalter sein, der dann über das zweite Argument der `execute()`-Methode mit einem Wert versorgt wird.
Das `os.chdir()` vergiss bitte mal gleich wieder. Zumal das hier überhaupt keinen Sinn macht. Dieser Aufruf verändert globalen Zustand. Das skaliert nicht und kann bei Fehlern problematisch werden.
Namen schreibt man in Python klein_mit_unterstrichen. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 09:31
von NewPython19
Danke erstmal für die schnellen Antworten
1. ich hab gesagt, dass mein Code nicht richtig ist
2. ich benutze das os.chdir(directory), weil meine Datenbank in einem bestimmten Verzeichnis erstellt ist. Was gibt es da für eine andere Möglichkeit, um den richtigen Pfad für die Datenbank zu errreichen/anzugeben?
3. Also muss ich das 'i' durch das (?) ersetzen? und wie binde ich das (?) in mein Programm ein? Kann ich das einfach anstelle von 'i' verwenden?
4. Mit der ID möchte ich sozusagen die Position des Datensatzes in der Datenbank bzw. Eingabereihenfolge angeben. Wenn ich es richtig verstanden habe, kann die auch automatisch erstellt werden?
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 09:38
von Sirius3
Hast Du eigentlich meinen Beitrag gelesen? Da sind alle Deine Fragen beantwortet.
Zu 4: Wenn ein Feld als `INTEGER PRIMARY KEY` typisiert ist, dann geht das automatisch.
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 09:47
von NewPython19
Ich hab deinen Beitrag gelesen.
Ich hab doch nur nochmal nachgefragt
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 10:20
von __blackjack__
Wenn das wirklich die Eingabereihenfolge widerspiegeln soll, braucht man noch AUTOINCREMENT. Sonst können kleinere IDs wiederverwendet werden wenn Datensätze gelöscht werden. Das hat aber auch Nachteile/Kosten. Nachzulesen in der SQLite-Dokumentation:
https://sqlite.org/autoinc.html
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 10:42
von __deets__
Wenn du mit
Code: Alles auswählen
os.chdir(directory)
connection = sqlite3.connect(database)
ans Ziel kommst, dann kommst du auch mit
Code: Alles auswählen
connection = sqlite3.connect(os.path.join(directory, database))
dahin.
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 11:03
von NewPython19
__blackjack__ hat geschrieben: ↑Dienstag 23. Juli 2019, 10:20
Wenn das wirklich die Eingabereihenfolge widerspiegeln soll, braucht man noch AUTOINCREMENT. Sonst können kleinere IDs wiederverwendet werden wenn Datensätze gelöscht werden. Das hat aber auch Nachteile/Kosten. Nachzulesen in der SQLite-Dokumentation:
https://sqlite.org/autoinc.html
Vielen Dank!
__deets__ hat geschrieben: ↑Dienstag 23. Juli 2019, 10:42
Wenn du mit
Code: Alles auswählen
os.chdir(directory)
connection = sqlite3.connect(database)
ans Ziel kommst, dann kommst du auch mit
Code: Alles auswählen
connection = sqlite3.connect(os.path.join(directory, database))
dahin.
Dankeschön!
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 14:26
von NewPython19
Eine weitere Frage
Wenn ich mit SELECT die Inhalte eines Datenfelds haben möchte und in eine Liste schreiben möchte (also alle Werte eines Datenfeldes von allen Datensätzen), wie erhalte ich da nur das eine Feld als String und nicht als Tupel?
connection = sqlite3.connect(database)
cursor = connection.cursor()
sql_command = """SELECT Name FROM 'Adress'"""
str(cursor.execute(sql_command))
for name in cursor:
list.append(name)
closeDatabase(connection, cursor) #schließt Verbindung und Cursor
So erhalte ich immer eine Liste mit z. B. [('Meier',), ('Müller',), ('Mustermann',)]
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 14:44
von Sirius3
Du erhältst immer Tuple. Wenn Du die nicht haben willst, entpack sie einfach.
`list` ist ein besonders schlechter Variablenname. Was macht denn `closeDatabase`? Arbeite besser mit with-closing.
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 14:52
von NewPython19
"closeDatabase" ist eine Methode von mir, welche die Verbindung zur Datenbank und den Cursor schließt
Danke!
Re: Datenfeld mit For befüllen
Verfasst: Dienstag 23. Juli 2019, 15:51
von __blackjack__
@NewPython19: Was die Funkion macht ist ja eigentlich schon klar, aber wie schon gesagt ist es besser ``with`` und `contextlib.closing()` zu verwenden. Der Kommentar bei der Zeile wäre auch nicht nötig gewesen.
Ich glaube ich erwähnte schon mal, das man Namen in Python klein_mit_unterstrichen schreibt, also `close_database()` statt `closeDatabase()`.
Es wäre schön wenn Du den Code in die entsprechenden Code-Tags einfasst und nicht als Zitat, denn dabei geht die in Python nicht ganz unwichtige Einrückung in der Anzeige verloren.
Bei Namen in SQL ist Gross-/Kleinschreibung eigentlich egal, aber einige DBMS können da doch Unterschiede machen. Deshalb würde ich Namen dort immer klein schreiben. Dann ist man auch bei einem DBMS-Wechsel auf der sicheren Seite.
Das englische Wort „address“ schreibt sich mit zwei „d“.
Das der Rückgabewert von `cursor.execute()` in eine Zeichenkette umgewandelt wird, mit der dann nicht gemacht wird, macht keinen Sinn.
`list` ist ein sehr schlechter Name für eine Liste, weil man sich damit den Namen des eingebauten Datentyps verdeckt. Grunddatentypen haben in Namen auch nichts verloren.
Das Entpacken eines einzelnen Wertes per ``,`` finde ich persönlich ein bischen zu kryptisch. Das übersieht man leicht.
Ungetestet:
Code: Alles auswählen
import sqlite3
from contextlib import closing
with sqlite3.connect(database) as connection:
with closing(connection.cursor()) as cursor:
cursor.execute('SELECT name FROM address')
names = [row[0] for row in cursor]