如何在Python中跳过SQLite的列?

0 投票
3 回答
2043 浏览
提问于 2025-04-17 12:13

我刚开始学习Python,写了一个简单的Python脚本,目的是把CSV文件里的数据插入到SQLite数据库中。我已经成功完成了这部分工作,不过我需要在插入时不包括第26、27和28列(总共有29列)。每次我尝试这样做时,整行数据都会被跳过,但我其实只想跳过那几列。最开始创建表的时候,我尝试不包括这些列,但每次运行脚本时都会报错。

这是我在这个过程中使用的代码:

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 个回答

1

如果我没记错的话,csv.reader 返回的是行,而不是列。

不过,有一种简单粗暴的方法(可能效率不高)可以做到这一点,那就是使用内置的 pop 函数。这个函数可以从返回的列表中移除某些项目。为了简单起见,建议从后往前进行 pop(先处理数组中索引最大的元素),否则随着数组变小,元素的位置会移动,可能会让人感到困惑。

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

cu.execute(sql_insert, line)
2

csv.reader()的工作方式是返回一个个列表,每个列表代表一行数据。所以如果你有一个这样的csv文件:

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

那么通过csv.reader()得到的内容看起来是这样的:

>>> 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']

列表的一个好处是你可以对它们进行切片,也就是可以选择其中的一部分。

>>> 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']

这是一种很简单的方法,可以跳过csv表格的最后几列。你还可以把多个列表的切片连接在一起:

>>> 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']

把这些内容结合起来:

>>> 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')]
1

你正在把csv.reader()的输出当成列来遍历,这样是不对的。实际上,它们是整行数据。你应该这样做:

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代替%s

撰写回答