コンフリクトを変更した。
成果物
やりたいこと
更新日時とURLが一致したら同一記事と判断して登録しないようにしたい。
実装
insert
時にコンフリクトさせる。
バグ
insert or fail
だと一意制約エラーになったら、そこで中断されてしまい、それ以降の記事も登録されない。これが不都合なときがある。たとえば異なるカテゴリのRSSを2回に分けて取り込むとき。1回目と2回目で重複するニュースがあったが、それ以降には未登録なニュースがあるとき。最初に重複があるので以降は取り込まれない。
def __insert_sql(self): return 'insert or fail into news(published,url,title,body) values(?,?,?,?)'
修正
そこで、insert or ignore
にしてみた。こちらによると、制約違反したところはスキップされて継続されるとある。これで最初のほうに一意制約エラーがあっても、それ以降に未登録があれば登録してくれるはず。
def __insert_sql(self): return 'insert or ignore into news(published,url,title,body) values(?,?,?,?)'
この変更に伴い、以下の一意制約エラー時はpass
するコードは不要となったので削除した。
except sqlite3.IntegrityError as err_sql_integ: import traceback import sys msg = str(err_sql_integ.with_traceback(sys.exc_info()[2])).lower() # UNIQUE constraint failed: news.published, news.url # DB既存と重複した時点で中断する if ('UNIQUE'.lower() in msg and 'published' in msg and 'url' in msg): pass # それ以外ならエラー表示&ロールバックする else: traceback.print_exc() self.conn.rollback()
所感
SQLite3の機能を使えば、Pythonコードがどんどん削れていく。いいね。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- Python 3.5.3
- SQLite 3.29.0 ※
- MeCab 0.996ユーザ辞書
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux