[newbie] Catch error when inserting duplicate in BEGIN+END block
(1.1) By Gilles on 2022-08-09 12:55:43 edited from 1.0 [link] [source]
Hello,
As an easy way to prune out duplicates, I'm thinking of adding records into an SQLite, and just ignore the error when trying to add a duplicate.
What is the right way to catch the error when using a BEGIN+END block?
Thank you.
#Python 3
db = sqlite3.connect('temp.sqlite')
cursor = db.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS wp(id INTEGER PRIMARY KEY,name TEXT UNIQUE,latitude TEXT,longitude TEXT)')
db.commit()
cursor.execute('BEGIN')
wps = tree.findall("wpt")
for wp in wps :
name = wp.find('name').text
lat = wp.attrib['lat']
lon = wp.attrib['lon']
print(name,lat,lon)
#How to catch error when inserting dup?
cursor.execute('INSERT INTO wp(name,latitude,longitude) VALUES(?)', name,lat,lon)
cursor.execute('END')
db.commit()
db.close()
(2) By Donal Fellows (dkfellows) on 2022-08-09 11:37:06 in reply to 1.0 [link] [source]
Wrap your code in:
```
these sort of triple backticks
```
and they'll mark the code as code.
(3) By David Raymond (dvdraymond) on 2022-08-09 11:44:10 in reply to 2 [link] [source]
Or alternatively, if you don't need any fancy formatting there's a dropdown at the top of the reply that you can change from "Markup" to "Plain Text"
(4) By David Raymond (dvdraymond) on 2022-08-09 11:53:16 in reply to 1.0 [link] [source]
Since you've got 3 values that you're binding, there should be 3 placeholders in the query text, and a single 3 item iterable passed for the bind values. cursor.execute("INSERT INTO wp (name, latitude, longitude) VALUES (?,?,?);", (name, lat, lon)) Then just run it and look at the exception type you're getting. sqlite3.IntegrityError: UNIQUE constraint failed: wp.name So check for that try: cursor.execute("INSERT INTO wp (name, latitude, longitude) VALUES (?,?,?);", (name, lat, lon)) except sqlite3.IntegrityError: pass Or optionally check err.args to make sure it's the same error you're looking for, in case there might be a different type of integrity problem try: cursor.execute("INSERT INTO wp (name, latitude, longitude) VALUES (?,?,?);", (name, lat, lon)) except sqlite3.IntegrityError as err: if err.args != ('UNIQUE constraint failed: wp.name',): raise
(5) By Ryan Smith (cuz) on 2022-08-09 12:56:31 in reply to 2 [link] [source]
Indeed - it'll be worthwhile to check out some "markdown" formatting help pages to see how it works, it's pretty simple once you know it, but like everything else, when you do not know it at all, it's not.
Some basics:
Headings start with double Hashes
Emphasize items between asterisks
code go in between in 3-backtick markers
And - in these fossil-based forums there's a particularly nifty addition where you can use PikChr text-based graphic renderer (also designed by the SQLite team) directly in the body by using the pikchr tags, like so: (Click it to view the code)
// NUCLEAR WARNING $segAngle = 60; // 360 / 6 segments $startAngle = 30; // sign has segments at 30 deg offset dot color white; move right 2; // margin CP: dot; $a = $startAngle; $r = 1; define segment { move to CP; line go $r heading $a then go $r heading $a+($segAngle*2) then go 1 heading $a+($segAngle*4) then close fill $1; $a += $segAngle; } define rim { circle at CP radius $r thick thick color $1; $r -= 0.025; } // Draw segments in alternating colours segment(black); segment(orange); segment(black); segment(orange); segment(black); segment(orange); // Draw outer rim rim(black); rim(black); rim(orange); rim(orange); rim(orange); rim(orange); rim(orange); // Go small radius to draw inner rim $r = 0.25; rim(orange); rim(orange); rim(orange); rim(orange); // And finally inner-most circle circle at CP radius 0.175 fill black; // EOF→ /pikchrshow
And finally links go in parentheses following its description in square brackets, for example:
To test your Pikchr design, try the pikchr fiddle over at: pikchr.org/home/pikchrshow.
(6) By Gilles on 2022-08-09 13:09:32 in reply to 4 [source]
Thanks much!
(7) By Keith Medcalf (kmedcalf) on 2022-08-09 17:10:00 in reply to 6 [link] [source]
Or, of course, if you know there will be duplicates and you know you always want to ignore them, then you can simply tell the statement conflict resolution mechanism to ignore the errors (INSERT or IGNORE INTO ...
). If you only want to ignore index conflicts against the name
indexed column (ie, it is delared unique) then you can INSERT INTO ... ON CONFLICT (name) DO NOTHING
.
Note that the first (insert or ignore) uses statement level conflict handling which may be overriden or changed so as to not be in accordance with your command (that is, you say OR IGNORE but a conflict is not ignored, or you do not say OR IGNORE but statement conflicts are ignored) in specific cases.
Note that the second (insert into ... on conflict ...) uses the specific index conflict resolution method particular to the insert statement and your command will be followed without exception.