[Tutor] catching the row that raises IntegrityError in sqlite
abhinav raj kp nirmallur
abhinavrajkp at gmail.com
Sun Feb 9 12:38:02 CET 2014
Sir I don't know nothing about programming but I have a great intrest
in it so that now a days I began to study python, many of my friends
and teachers suggest me it. But still I have no tutor, can you please
suggest me to study python using book or any good websit.
Thanks.
Abhinav Raj
>From Calicut, Kerala, India.
I'm currently studying in plus one science.
On 2/9/14, Peter Otten <__peter__ at web.de> wrote:
> Sivaram Neelakantan wrote:
>
>>
>> I've written this code that seems to work and I'd like to know how to get
>> the record that causes the abort. Apparently 'executemany' doesn't
>> support lastrow? And if it doesn't, any suggestions?
>>
>> --8<---------------cut here---------------start------------->8---
>> def table_load(datafile,name,conn,dbh):
>> print "processing table ",name
>> conn.execute("PRAGMA table_info("+ name +")")
>> #parse the resultset to get the col name
>> cols= [ x[1] for x in conn.fetchall()]
>> cv= ("?" * len(cols))
>> with open(datafile,'r') as fin:
>> dr = csv.reader(fin, delimiter='|')
>> to_db = [tuple(i) for i in dr]
>> print "Records read in: ", len(to_db)
>> cl=','.join(cols)
>> cvv=','.join(cv)
>> try:
>> sql = "insert into %s (%s) values(%s)" %(name, cl, cvv)
>> conn.executemany(sql, to_db)
>> dbh.commit()
>> except sq.IntegrityError:
>> print('Record already exists') # but which record???
>> dbh.rollback()
>> finally:
>> sql= "select count(*) from %s;" %(name)
>> (row_cnt,) = conn.execute(sql).fetchone()
>> print "rows inserted ", row_cnt
>> --8<---------------cut here---------------end--------------->8---
>>
>> And do tell if I'm doing this try catch bits correctly please.
>
> If nobody here comes up with a good way to find the offending record you
> could ask in a mailing list/newsgroup dedicated to sqlite (Please report
> back here if you do). If there is no "official" way you might try the
> workaround shown below.
>
> The idea here is to wrap the iterable of records to be inserted in the Iter
>
> class which keeps track of the last accessed row.
>
> $ cat sqlite_integrity2.py
> import sqlite3
> import csv
> import sys
>
> class Iter(object):
> def __init__(self, items):
> self.items = items
> def __iter__(self):
> for item in self.items:
> self.last = item
> yield item
>
> def table_load(datafile, name, cursor, db):
> print("processing table {}".format(name))
> cursor.execute("PRAGMA table_info("+ name +")")
> column_names = [descr[1] for descr in cursor.fetchall()]
>
> with open(datafile,'r') as fin:
> records = csv.reader(fin, delimiter='|')
> records = Iter(records)
> sql = "insert or rollback into {name} ({columns})
> values({qmarks})".format(
> name=name,
> columns=", ".join(column_names),
> qmarks=", ".join("?"*len(column_names)))
> try:
> cursor.executemany(sql, records)
> except sqlite3.IntegrityError as err:
> print("{}: {}".format(err, records.last))
> finally:
> sql= "select count(*) from {};".format(name)
> [row_count] = cursor.execute(sql).fetchone()
> print("rows inserted: {}".format(row_count))
>
> if __name__ == "__main__":
> filename = sys.argv[1]
> db = sqlite3.connect(":memory:")
> cursor = db.cursor()
> cursor.execute("create table demo (name unique, value);")
> table_load(filename, "demo", cursor, db)
> $ cat records_
> records_conflict.csv records_no_conflict.csv
> $ cat records_conflict.csv
> alpha|1
> beta|2
> gamma|3
> alpha|4
> delta|5
> $ python sqlite_integrity2.py records_conflict.csv
> processing table demo
> column name is not unique: ['alpha', '4']
> rows inserted: 0
> $ cat records_no_conflict.csv
> alpha|1
> beta|2
> gamma|3
> delta|4
> $ python sqlite_integrity2.py records_no_conflict.csv
> processing table demo
> rows inserted: 4
>
> While this approach seems to work at the moment it will of course break
> should sqlite decide one day to read records ahead before performing the
> integrity test. Therefore I recommend the more conservative road to loop
> over the records explicitly:
>
> for row in records:
> try:
> cursor.execute(sql, row)
> except ...
> ...
>
>
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
More information about the Tutor
mailing list