Hallo zusammen,
ich bin neu in diesem Forum und experimentiere gerade mit Python (verwende die Version Python 3.10.0) und mySQL (Version 8.0.26).
Trotz intensiver Recherche im Netz und diesem Forum habe ich jetzt keine Lösung für mein aktuelles Problem gefunden.
Deshalb hoffe ich, dass die Profis in diesem Forum mir hier weiterhelfen können.
Dafür schon mal vorab vielen Dank!
Ich habe die Tabelle 'countries' in der DB 'countrydb' erstellt:
"CREATE TABLE countries ("
" country_numeric INTEGER(3),"
" last_update TIMESTAMP DEFAULT CURRENT_TIMESTAMP,"
" country_name_official VARCHAR(255) NOT NULL,"
" PRIMARY KEY (country_numeric)"")")
Die Abfrage showTBL ergibt folgendes Ergebnis:
================ RESTART: Python-Code/CCmysql_showTBL.py ===============
('countries',)
Wenn ich nun meine INSERT-Funktion laufen lasse (siehe weiter unten), erhalte ich als 'rowcount' immer das Ergebnis "-1".
================== RESTART: Python-Code/CCIBANcsv4.py ==================
INSERT INTO countries (country_numeric, country_name_official, last_update) VALUES (%s, '%s', '%s');
004 / Afghanistan
Total number of rows in table: -1
008 / Albania
Total number of rows in table: -1
Beim Versuch über SELECT Werte aus der Tabelle auszulesen, kommt - vermutlich zu recht - das Ergebnis: "NONE".
=============== RESTART: Python- Code/CCmysql_selectTBL.py ==============
SELECT * FROM countries
None
Wie gesagt, ich beschäftige mich erst seit kurzem mit Python, deshalb bitte nicht allzu kritisch auf mein Coding schauen - ich lerne noch
Wo ist mein Fehler???
===============
from datetime import datetime
import sys
import mysql.connector
import csv
current_timestamp = datetime.now()
insert_timestamp = current_timestamp.strftime('%Y-%m-%d %H:%M:%S')
try:
mydb = mysql.connector.connect(
host="localhost",
user="xxxxxxxx",
password="xxxxxxxx",
database="countrydb")
except:
print ("Keine Verbindung zum Server")
sys.exit(0)
insert_sql = print( "INSERT INTO countries (country_numeric, country_name_official, last_update) VALUES (%s, '%s', '%s');" );
with open('Country-Code-IBAN.csv') as csvfile:
reader = csv.DictReader(csvfile, delimiter = ';')
for row in reader:
print(row['Code-Numeric'], "/", row['Country'])
mycursor = mydb.cursor()
try:
mycursor.execute(insert_sql, [(row['Code-Numeric'], row['Country'], {insert_timestamp})])
mydb.commit()
print("Total number of rows in table: ", mycursor.rowcount)
except mysql.connector.Error as error:
print(f"Oh no, something went wrong.\nIt was: {error}")
mydb.rollback()
sys.exit(0)
mycursor.close()
if mydb.is_connected():
mydb.close()
print("MySQL connection is closed")
sys.exit(0)
mysql:insert schreibt nicht in DB trotz commit()
Eingerückt wird in Python immer mit 4 Leerzeichen pro Ebene, nicht 2.
Nackte except darf man nicht benutzen, weil damit auch viele Programmierfehler verdeckt werden. Die sprechenden Fehlermeldungen durch nichtssagende zu verdecken, ist auch wenig hilfreich.
sys.exit hat in einem normalen Programm nichts verloren, vor allem nicht, wenn damit immer per Exitcode 0 suggeriert wird, dass alles fehlerfrei lief.
Mit Datenbanken benutzt man immer die passenden Datentypen, ein Datetime-Objekt explizit in einen String umzuwandeln ist daher falsch.
`print` hat als Rückgabewert None, das an insert_sql zu binden ist nicht sinnvoll.
Die Platzhalter in SQL-Statements werden immer ohne Anführungszeichen benutzt.
csv-Dateien öffnet man immer mit explizitem Encoding und newline="".
Die Datenbank heißt zwar mysql aber deshalb muß man nicht an alle Variablennamen ein my anhängen.
Warum steckst Du für execute die Parameter in eine Liste aus einem Tuple, das ein Set enthält? execute braucht genau ein Tuple.
Nackte except darf man nicht benutzen, weil damit auch viele Programmierfehler verdeckt werden. Die sprechenden Fehlermeldungen durch nichtssagende zu verdecken, ist auch wenig hilfreich.
sys.exit hat in einem normalen Programm nichts verloren, vor allem nicht, wenn damit immer per Exitcode 0 suggeriert wird, dass alles fehlerfrei lief.
Mit Datenbanken benutzt man immer die passenden Datentypen, ein Datetime-Objekt explizit in einen String umzuwandeln ist daher falsch.
`print` hat als Rückgabewert None, das an insert_sql zu binden ist nicht sinnvoll.
Die Platzhalter in SQL-Statements werden immer ohne Anführungszeichen benutzt.
csv-Dateien öffnet man immer mit explizitem Encoding und newline="".
Die Datenbank heißt zwar mysql aber deshalb muß man nicht an alle Variablennamen ein my anhängen.
Warum steckst Du für execute die Parameter in eine Liste aus einem Tuple, das ein Set enthält? execute braucht genau ein Tuple.
Code: Alles auswählen
import csv
from datetime import datetime
from contextlib import closing
import mysql.connector
current_timestamp = datetime.now()
database = mysql.connector.connect(
host="localhost",
user="xxxxxxxx",
password="xxxxxxxx",
database="countrydb")
insert_sql = "INSERT INTO countries (country_numeric, country_name_official, last_update) VALUES (%s, %s, %s)"
with closing(database):
with open('Country-Code-IBAN.csv', encoding="utf8", newline="") as csvfile:
reader = csv.DictReader(csvfile, delimiter=';')
for row in reader:
print(row['Code-Numeric'], "/", row['Country'])
with closing(database.cursor()) as cursor:
cursor.execute(insert_sql, (row['Code-Numeric'], row['Country'], insert_timestamp))
database.commit()
print("Total number of rows in table: ", cursor.rowcount)
... ahhh, Danke!!!
Da hätte ich auch selbst drauf kommen können, aber manchmal sieht man den Wald vor lauter Bäumen nicht
Habe die Anweisung entsprechend umgebaut und nun funktioniert es!
Super, vielen Dank für die schnelle Rückmeldung.
Sirius3 hat geschrieben: ↑Donnerstag 21. Oktober 2021, 09:35 Eingerückt wird in Python immer mit 4 Leerzeichen pro Ebene, nicht 2.
Nackte except darf man nicht benutzen, weil damit auch viele Programmierfehler verdeckt werden. Die sprechenden Fehlermeldungen durch nichtssagende zu verdecken, ist auch wenig hilfreich.
sys.exit hat in einem normalen Programm nichts verloren, vor allem nicht, wenn damit immer per Exitcode 0 suggeriert wird, dass alles fehlerfrei lief.
Mit Datenbanken benutzt man immer die passenden Datentypen, ein Datetime-Objekt explizit in einen String umzuwandeln ist daher falsch.
`print` hat als Rückgabewert None, das an insert_sql zu binden ist nicht sinnvoll.
Die Platzhalter in SQL-Statements werden immer ohne Anführungszeichen benutzt.
csv-Dateien öffnet man immer mit explizitem Encoding und newline="".
Die Datenbank heißt zwar mysql aber deshalb muß man nicht an alle Variablennamen ein my anhängen.
Warum steckst Du für execute die Parameter in eine Liste aus einem Tuple, das ein Set enthält? execute braucht genau ein Tuple.Code: Alles auswählen
import csv from datetime import datetime from contextlib import closing import mysql.connector current_timestamp = datetime.now() database = mysql.connector.connect( host="localhost", user="xxxxxxxx", password="xxxxxxxx", database="countrydb") insert_sql = "INSERT INTO countries (country_numeric, country_name_official, last_update) VALUES (%s, %s, %s)" with closing(database): with open('Country-Code-IBAN.csv', encoding="utf8", newline="") as csvfile: reader = csv.DictReader(csvfile, delimiter=';') for row in reader: print(row['Code-Numeric'], "/", row['Country']) with closing(database.cursor()) as cursor: cursor.execute(insert_sql, (row['Code-Numeric'], row['Country'], insert_timestamp)) database.commit() print("Total number of rows in table: ", cursor.rowcount) [/quote] .. vielen Dank für deine Rückmeldung, ich schaue wie ich das in Zukunft besser machen kann. Aber wie bereits gesagt: "Wie gesagt, ich beschäftige mich erst seit kurzem mit Python, deshalb bitte nicht allzu kritisch auf mein Coding schauen - ich lerne noch ;-)"