使用Python加载SQLite数据库表:未找到表
我正在使用 Python 2.7,想把一个用管道符分隔的文件加载到 SQLite 表中。
最开始我尝试使用事务处理,但遇到了一个错误:“操作错误:没有这样的表:ff”。我在函数里加了一个全局声明,但也没用(其实我也没指望它能解决问题,只是想确认一下)。
为了调试,我把函数调用去掉了,直接在循环里加了 INSERT 语句,结果还是同样的错误。
我检查了一下:clt.db 文件已经创建,并且里面有一个空的表 ff。错误发生在第 64 行(curs.execute(insertStmt,obs),因为行号被删掉了)。
我不知道这是否会影响解决方案(希望不会):我是在一个微型 EC2 实例上运行这个程序,目标数据库写入的是通过 s3fs 挂载的 S3 存储桶。可能是延迟问题?
--更新:我发现当我关闭连接和游标,然后再重新打开它们时,这个问题就解决了。即使在执行 conn.commit() 之后也一样。我尝试了 time.sleep(),但没有帮助,所以看起来连接和游标真的需要关闭再重新打开,才能让新表的存在被识别。为什么会这样我也不知道。有谁能给点建议吗?
有什么想法吗?谢谢。
Aust。
import csv,sqlite3
dbName = 'clt.db'
conn = sqlite3.connect(dbName)
curs = conn.cursor()
def loadBloc(bloc):
global conn,curs
curs.execute('begin')
for obs in bloc:
curs.execute(insertStmt,obs)
conn.commit()
return None
createCode = '''
create table ff
(
a text not null,
b text not null,
c text not null,
d numeric not null,
e text not null,
f text not null,
g text not null,
h numeric not null,
i numeric not null
);
'''
curs.execute(createCode)
conn.commit()
nb = 10000; cnt = 0
bloc = ["" for i in range(nb)]
f = open(infile,'rt')
csv.register_dialect('pipes',delimiter='\t')
with open('ff.dat','r') as f:
reader = csv.reader(f,dialect='pipes')
for row in reader:
a = row[0]
b = row[1]
c = row[2]
u = c.split('/')
if len(u) == 3:
v = [int(u[i]) for i in range(len(u)) ]
c = "{0:4d}-{1:02d}-{2:02d}".format(v[2],v[1],v[0])
else:
c = "1212-12-12"
d = row[3]
e = row[4]
f = row[5]
g = row[6]
h = row[7]
i = row[8]
obs = (a,b,c,d,e,f,g,h,i)
insertStmt = 'insert into ff (a,b,c,d,e,f,g,h,i) values (' + ','.join('?'*9) + ');'
curs.execute(insertStmt,obs)
conn.commit()
print cnt
#bloc[cnt] = (a,b,c,d,e,f,g,h,i)
#if cnt == nb-1:
# loadBloc(bloc)
# print "=============================================="
# bloc = ["" for i in range(nb)]
# cnt = 0
#else:
# cnt = cnt + 1
f.close()
curs.close()
conn.close()
1 个回答
0
你的代码看起来没有明显的问题。在去掉所有没用的代码后,剩下的代码变得简洁了一些,并且让cnt
去计算一些东西,代码就能正常运行了,下面是运行的结果,只有一个提交(就在结束之前)。我建议你先在一个非云端的系统上试试这段代码,以确保Python、sqlite或csv没有问题。然后再在你怀疑的实例上运行,如果需要的话,可以在其他地方也试试。
[ff.py]
import csv,sqlite3
dbName = 'clt.db'
conn = sqlite3.connect(dbName)
curs = conn.cursor()
createCode = '''
create table ff
(
a text not null,
b text not null,
c text not null,
d numeric not null,
e text not null,
f text not null,
g text not null,
h numeric not null,
i numeric not null
);
'''
insertStmt = (
'insert into ff (a,b,c,d,e,f,g,h,i) values (' +
','.join('?'*9) +
');'
)
curs.execute(createCode)
# conn.commit() # works ok without this
with open('ff.dat','r') as f:
reader = csv.reader(f,delimiter='|')
for cnt, row in enumerate(reader, 1):
a,b,c,d,e,f,g,h,i = row
u = c.split('/')
if len(u) == 3:
v = [int(x) for x in u]
c = "{0:4d}-{1:02d}-{2:02d}".format(v[2],v[1],v[0])
else:
c = "1212-12-12"
obs = (a,b,c,d,e,f,g,h,i)
curs.execute(insertStmt,obs)
# conn.commit() # doesn't need to be inside the loop
print "row number:", cnt
curs.close()
conn.commit() # need at least 1 commit
conn.close()
[transcript]
C:\junk\so>del clt.db
C:\junk\so>type ff.dat
A|B|C|D|E|F|G|H|I
1|2|16/10/2011|4|5|6|7|8|9
C:\junk\so>\python27\python ff.py
row number: 1
row number: 2
C:\junk\so>\bin\sqlite3 clt.db
SQLite version 3.6.14
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from ff;
A|B|1212-12-12|D|E|F|G|H|I
1|2|2011-10-16|4|5|6|7|8|9
sqlite> ^Z
C:\junk\so>