Premiär! Fyndchans i SweClockers Månadens Drop
Permalänk
Medlem

Python - Mysql - import .csv

Hej,

Jag är nybörjare på Python och försöker göra ett skript som importerar en .csv fil till min sql databas.

Jag får följande fel:

Traceback (most recent call last):
File "csvimport.py", line 17, in <module>
row)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 159, in execute
query = query % db.literal(args)
TypeError: not enough arguments for format string

Här är koden jag använder:

#!/usr/bin/python import csv import MySQLdb mydb = MySQLdb.connect(host='localhost', user='root', passwd='', db='data') cursor = mydb.cursor() csv_data = csv.reader(file('/home/data.csv')) for row in csv_data: cursor.execute('INSERT INTO testcsv(names, \ classes, mark )' \ 'VALUES("%s", "%s", "%s","%s")', row) #close the connection to the database. mydb.commit() cursor.close() print "Done"

Jag har 4 kolumner i .csv-filen, så borde inte ("%s", "%s", "%s","%s")', vara tillräckligt då? Eller ligger felet på annat ställe?

Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Medlem

du måste nog hänvisa mer specifikt. Typ:

cursor.execute('INSERT INTO testcsv(names, \ classes, mark )' \ 'VALUES("%s", "%s", "%s","%s")', row[0], row[1], row[2], row[3])

om det nu är så den indexerar raden.

Visa signatur

Jag är en optimist; det är aldrig så dåligt så att det inte kan bli sämre.

Permalänk
Medlem

IndexError: list index out of range

Tack för förslaget. Testade detta och fick nu följande fel:

Traceback (most recent call last):
File "csvimport.py", line 17, in <module>
row[0], row[1], row[2], row[3])
IndexError: list index out of range

Funderade på om filen verkligen har 4 kolumner, dubbelkollade detta. Men ja det stämmer att det är 4, även om jag testade lägga till ännu en %s och ännu en row[5], där jag fick samma IndexError.

Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Hedersmedlem

För framtida informations skull så försöker du i din SQL-fråga för närvarande att stoppa in fyra värden i tre kolumner (`names`, `classes`, `mark`).

Däremot så klagar Python på att din variabel `row` inte innehåller fyra element i båda fall. Testa att skriva ut `row` med bara

print(row)

för att se vad den faktiskt innehåller för att komma vidare. Kanske använder du fel fältavgränsare så att Python tror att du bara har ett enda fält på varje rad, eller något.

——

För att utveckla så betyder `TypeError: not enough arguments for format string` att du vill ha fyra strängar in för att kunna ersätta de fyra `%s` du angivit, men att `row` alltså inte ger tillräckligt många värden.

På samma sätt så betyder `IndexError: list index out of range` att något av elementanropen på raden inte är OK, eftersom det anropade indexet inte existerar. Exakt vilket går inte att urskilja då alla sker på samma rad, men i praktiken blir det bara en omskrivning av samma fel som ovan.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Rent spontant hade jag gissat på att du inte har default delimiter. I USA använder man "," för att separera värden i csv filer men i sverige använder man rent generellt ";". Om du inte specificerar kommer python defualta till att anta att det är "," medans t.ex. svenska excel sparar .csv filer med ";" som delimiter. Om så är fallet får du alltid bara 1 värde per rad.

Permalänk
Medlem

>>> import csv
>>> with open('eggs.csv', 'rb') as csvfile:
... spamreader = csv.reader(csvfile, delimiter=';', quotechar='|')
... for row in spamreader:
... print ', '.join(row)
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam

Permalänk
Medlem

Misstänker att det kan vara som ni, Mackan32 och phz föreslår med delimiter. För jag använder semikolon ( ; ) i min csv och jag har inte angivit vad min delimiter ska vara.

Osäker på hur jag implementerar detta på rätt sätt i min nuvarande kod, är som sagt nybörjade (även på mysql).

Den gillar iaf inte min syntax på detta:

for row in csv_data: print (row) cursor.execute('delimiter = ';',\ INSERT INTO testcsv(names, \ classes, mark, other )' \ ....etc

Felmeddelande:

File "csvimport.py", line 14 cursor.execute('delimiter = ';',\ ^ SyntaxError: invalid syntax

Ja, ni får ursäkta min "noobighet", som ni kanske märker så är jag nybörjade på detta

Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Hedersmedlem
Skrivet av Asce:

Misstänker att det kan vara som ni, Mackan32 och phz föreslår med delimiter. För jag använder semikolon ( ; ) i min csv och jag har inte angivit vad min delimiter ska vara.

Osäker på hur jag implementerar detta på rätt sätt i min nuvarande kod, är som sagt nybörjade (även på mysql).

Den gillar iaf inte min syntax på detta:

for row in csv_data: print (row) cursor.execute('delimiter = ';',\ INSERT INTO testcsv(names, \ classes, mark, other )' \ ....etc

Felmeddelande:

File "csvimport.py", line 14 cursor.execute('delimiter = ';',\ ^ SyntaxError: invalid syntax

Ja, ni får ursäkta min "noobighet", som ni kanske märker så är jag nybörjade på detta

Du ska ge `delimiter` som ett argument till `csv.reader`. Se manualen för `csv`-modulen (som Mackan32 kopierade sitt exempel från). Jag länkar till Python 2.7-versionen av manualen, då du av någon anledning valt att använda Python 2 i stället för Python 3 .

Skrev du ut `row` för att kunna titta på vad den innehöll? Det kan vara nyttigt för att se vad som händer, och förstå varför Python klagade som det gjorde.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Okej, tack för förklaringen.

Jag lyckades implementera det med delimitern som mackan32 skrev.

Jag följde nu också ditt förslag, phz, med att printa ut row för att se vad som hamnar där. För närvarande får jag följande felmeddelande:

['Online', ' blablabla.com.', ' 11.111.111.11', ' Hej'] Traceback (most recent call last): File "csvimport.py", line 25, in <module> row[0], row[1], row[2], row[3]) TypeError: execute() takes at most 3 arguments (6 given)

Min nuvarande kod (vissa delar bortkommenterade)

#!/usr/bin/python import csv import MySQLdb mydb = MySQLdb.connect(host='localhost', user='root', passwd='', db='data') cursor = mydb.cursor() with open ('/home/data.csv') as csvfile: #mydb = MySQLdb.connect(host='localhost', # user='root', # passwd='LoveLiver2', # db='emldata') #cursor = mydb.cursor() csv_data = csv.reader(csvfile, delimiter=';') #,file('/home/data.csv')) for row in csv_data: print (row) cursor.execute('INSERT INTO testcsv(test1, \ test2, test3, test4)' \ 'VALUES("%s", "%s", "%s", "%s")' , row[0], row[1], row[2], row[3]) #close the connection to the database. mydb.commit() cursor.close() print "Done"

Dold text
Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Hedersmedlem
Skrivet av Asce:

Okej, tack för förklaringen.

Jag lyckades implementera det med delimitern som mackan32 skrev.

Jag följde nu också ditt förslag, phz, med att printa ut row för att se vad som hamnar där. För närvarande får jag följande felmeddelande:

['Online', ' blablabla.com.', ' 11.111.111.11', ' Hej'] Traceback (most recent call last): File "csvimport.py", line 25, in <module> row[0], row[1], row[2], row[3]) TypeError: execute() takes at most 3 arguments (6 given)

Min nuvarande kod (vissa delar bortkommenterade)

#!/usr/bin/python import csv import MySQLdb mydb = MySQLdb.connect(host='localhost', user='root', passwd='', db='data') cursor = mydb.cursor() with open ('/home/data.csv') as csvfile: #mydb = MySQLdb.connect(host='localhost', # user='root', # passwd='LoveLiver2', # db='emldata') #cursor = mydb.cursor() csv_data = csv.reader(csvfile, delimiter=';') #,file('/home/data.csv')) for row in csv_data: print (row) cursor.execute('INSERT INTO testcsv(test1, \ test2, test3, test4)' \ 'VALUES("%s", "%s", "%s", "%s")' , row[0], row[1], row[2], row[3]) #close the connection to the database. mydb.commit() cursor.close() print "Done"

Dold text

`TypeError: execute() takes at most 3 arguments (6 given)` — Pythons felmeddelanden är rätt exemplariska . Så som du skriver nu ger du 6 argument till functionen `execute()`, som bara tar 3 argument (där det sista är en iterabel som i sig innehåller flera element; så många som du vill interpolera in i SQL-strängen). Du bör ersätta

row[0], row[1], row[2], row[3])

med

row)

Notera att detta tar bort 3 argument till funktionen `execute()`, där det sista argumentet `row` alltså innehåller fyra element.

Utskriften av `row` visar annars nu att en rad i din CSV-fil tolkas som just fyra element.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Tack så mycket. Det löste problemet

Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Medlem

Ojdå, får nog gräva upp tråden lite igen.

Får nu följande felmeddelande:

Traceback (most recent call last): File "csvimport.py", line 19, in <module> row) File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute self.errorhandler(self, exc, value) File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler raise errorclass, errorvalue _mysql_exceptions.ProgrammingError: (1146, "Table 'data.test' doesn't exist")

Dold text

Nuvarande kod:

#!/usr/bin/python import csv import MySQLdb mydb = MySQLdb.connect(host='localhost', user='root', passwd='', db='data') cursor = mydb.cursor() with open ('/home/mydata.csv') as csvfile: csv_data = csv.reader(csvfile, delimiter=';') for row in csv_data: print (row) cursor.execute('INSERT INTO test(names, \ classes, mark, other )' \ 'VALUES("%s", "%s", "%s","%s")', row) #close the connection to the database. mydb.commit() cursor.close() print "Done"

Dold text

Någon idé om vart felet ligger?

Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
SpelClockers
Skrivet av Asce:

Någon idé om vart felet ligger?

Citat:

"Table 'data.test' doesn't exist"

Finns denna tabell i databasen?

Permalänk
Medlem

Nej den finns inte där ännu. Trodde att den skapades om den inte redan fanns....noobigt, jag vet. Får skapa den först då.

Så jag tänkte sätta sql = "CREATE TABLE test" och sedan anropa den i rätt ordning, men får samma fel som förut.

För att vara så tydlig som möjligt, jag har redan en databas, där jag vill skapa en tabell i vilken .csv-filen importeras.
----

Kod:

mydb = MySQLdb.connect(host='localhost', user='root', passwd='', db='data') cursor = mydb.cursor() sql = "CREATE TABLE test" with open ('/home/mydata.csv') as csvfile: csv_data = csv.reader(csvfile, delimiter=';') for row in csv_data: print (row) cursor.execute('INSERT INTO test(names, \ classes, mark, other )' \ 'VALUES("%s", "%s", "%s","%s")', row) #close the connection to the database. mydb.commit() sql.commit() cursor.close()

Dold text
Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Hedersmedlem
Skrivet av Asce:

Nej den finns inte där ännu. Trodde att den skapades om den inte redan fanns....noobigt, jag vet. Får skapa den först då.

Så jag tänkte sätta sql = "CREATE TABLE test" och sedan anropa den i rätt ordning, men får samma fel som förut.

För att vara så tydlig som möjligt, jag har redan en databas, där jag vill skapa en tabell i vilken .csv-filen importeras.
----

Kod:

mydb = MySQLdb.connect(host='localhost', user='root', passwd='', db='data') cursor = mydb.cursor() sql = "CREATE TABLE test" with open ('/home/mydata.csv') as csvfile: csv_data = csv.reader(csvfile, delimiter=';') for row in csv_data: print (row) cursor.execute('INSERT INTO test(names, \ classes, mark, other )' \ 'VALUES("%s", "%s", "%s","%s")', row) #close the connection to the database. mydb.commit() sql.commit() cursor.close()

Dold text

Du är en ansenlig bit ifrån att lyckas skapa en tabell där; du måste även definiera kolumnnamn och -typer på ett vettigt sätt. Du får nog börja med att läsa mer om SQL-syntax. Kanske har du något grafiskt verktyg i stil med PhpMyAdmin eller liknande tillgängligt som kan vara till hjälp initialt för att administrera databasen och få en grafisk intuition för hur saker hänger ihop.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.