0

I'm very new to python and I have a basic python script where I need to insert values from a CSV file into an SQLite database using Python. I've done that part successfully, however, I need to not include columns 26, 27 and 28 out of 29. Whenever I try to do this, it just skips over the entire row, however I only want it to skip that specific column in general. I tried to not include the columns when creating the table originally however, I would get an error each time when I ran the script

This is the code I'm working with with regards to this process:

import sys, sqlite, csv

  try: 
    cx = sqlite.connect("database")

except sqlite.Error, errmsg:
    print "Could not open the database file: " + str(errmsg)
    sys.exit()

#create the table        
try:
    cu = cx.cursor()
    cu.execute('DROP TABLE IF EXISTS table_name')

    sql = """ CREATE TABLE table_name(col1 TEXT, col2 TEXT, col3 TEXT, col4 TEXT, col5 TEXT, col6 TEXT, col7 TEXT, col8 TEXT, col9 TEXT, col10 TEXT, col11 TEXT, col12 TEXT, col13 TEXT, col14 TEXT, col15 TEXT, col16 TEXT, col17 TEXT, col18 TEXT, col19 TEXT, col20 TEXT, col21 TEXT, col22 TEXT, col23 TEXT, col24 TEXT, col25 TEXT, col26 TEXT, col27 TEXT, col28 TEXT, col29 TEXT); """

    cu.execute(sql)
    cx.commit()
except sqlite.Error, errmsg:
    print "Could not execute the query: " + str(errmsg)
    sys.exit()

#Load the CSV file into the csv reader


fin = open("test.csv", "rb")
creader = csv.reader(fin, delimiter=',')

# Interate through the CSV Reader, inserting each value into the database
    # NEW REVISION
  sql_insert = "INSERT INTO table_name VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,,,,%s);"    


      for row in creader:
         cu.execute(sql_insert, row)
         print row

fin.close()
cx.commit()
cx.close()

3 Answers 3

2

The way csv.reader() works is that it returns lists, each of which represents a row. So if you have a csv file that looks like this:

col1, col2, col3, col4
a, b, c, d
e, f, g, h
i, j, k, l

The corresponding contents of csv.reader() look like this:

>>> with open('blah.csv', 'rb') as csv_file:
...     cr = csv.reader(csv_file)
...     for row in cr:
...         print row
... 
['col1', ' col2', ' col3', ' col4']
['a', ' b', ' c', ' d']
['e', ' f', ' g', ' h']
['i', ' j', ' k', ' l']

What's nice about lists is that you can slice them.

>>> with open('blah.csv', 'rb') as csv_file:
...     cr = csv.reader(csv_file)
...     for row in cr:
...         print row[0:3]
... 
['col1', ' col2', ' col3']
['a', ' b', ' c']
['e', ' f', ' g']
['i', ' j', ' k']

That's the most obvious way to skip the last few columns of a csv table. You can also concatenate slices of lists:

>>> with open('blah.csv', 'rb') as csv_file:
...     cr = csv.reader(csv_file)
...     for row in cr:
...         print row[0:2] + row[3:]
... 
['col1', ' col2', ' col4']
['a', ' b', ' d']
['e', ' f', ' h']
['i', ' j', ' l']

Putting it all together:

>>> with open('blah.csv', 'rb') as csv_file:
...     sql_insert = 'INSERT INTO table_name VALUES(?, ?, ?)'
...     for row in csv.reader(csv_file):
...         cu.execute(sql_insert, row[0:2] + row[3:])
... 
<sqlite3.Cursor object at 0x100535298>
<sqlite3.Cursor object at 0x100535298>
<sqlite3.Cursor object at 0x100535298>
<sqlite3.Cursor object at 0x100535298>
>>> cu.execute('SELECT * FROM table_name').fetchall()
[(u'col1', u' col2', u' col4'), (u'a', u' b', u' d'), (u'e', u' f', u' h'), (u'i', u' j', u' l')]
Sign up to request clarification or add additional context in comments.

4 Comments

Slicing and Concatenating, Much more elegant than my approach.
Thanks for the reply, I've tried that but I need to get to skip the rows being inserted into the database, so i tried to do your suggestion but it did not work unfortunately.
@user1186173, I don't really understand this comment. Do you need to skip rows or do you need to skip columns? Your question is only about skipping columns. But skipping rows is also easy; before inserting a row into the table, test the row for some condition and if it's true, continue -- as in if condition: continue. This will cause the for loop to skip to the next row.
I'm sorry I mean't columns, that was my fault. Thanks for your suggestion anyways
1

You are iterating over the output of csv.reader() as if they are columns. That is incorrect. They are in fact whole rows. It should be more like:

for row in reader:
    # Now to skip the mentioned columns just don't use those in your sql insert statement
    # for example column 25 is row[24]
    # Instead, put a blank in your SQL
    row[25]=""
    row[26]=""
    row[27]=""

    sql_insert = "INSERT INTO table_name   VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"  
    cursor.execute(sql_insert , row)

insert instead of %s for those columns

10 Comments

When I try to do that, I get an Error, "TypeError: not all arguments converted during string formatting" Thanks for responding so quickly
Instead of the empty commas can you put spaces like ...%s,"","","","",%s... i.e. spaces for strings and maybe 0 for ints or floats?
Problem is also with your sql insertion. You need to use questionmarks instead of %s. See this: stackoverflow.com/questions/2092757/…
I've tried that before as well and it would give me the same error
If this doesn't work the only thing I can think is that cursor.execute() requires a tuple for values with the insert rather than a list. Although I'd expect it would be any iterable.
|
1

If I remember correctly csv.reader returns lines, rather than columns.

Anyway a quick and dirty way (probably inefficient) of doing it would be to use the built in pop function. This should remove the items from the list returned. To keep it simple, do the pop in reverse order (highest array index first) otherwise it can get confusing as the array gets smaller and elements positions move

for line in creader:
   line.pop(28)
   line.pop(27)
   line.pop(26)

cu.execute(sql_insert, line)

2 Comments

Thanks, but I need to remove columns 26,27,28 and keep 29, so that would remove one too many columns..
it almost worked! But now i'm getting an error that there's not enough parameters

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.