При создании небольшого приложения с использованием SQLite я заметил странную вещь (для меня) с поведением алгоритма счетчиков автоинкрементов.SQLite AUTOINCREMENT поведение счетчика столбцов с опцией ON CONFLICT IGNORE
Например, давайте попробуем создать базу данных с помощью следующей схемы
CREATE TABLE numbers (num INTEGER UNIQUE ON CONFLICT IGNORE);
и небольшой Python скрипта
import sqlite3
con = sqlite3.connect('db.sqlite3')
cur = con.cursor()
def values():
for i in xrange(1, 3):
yield (i,)
try:
cur.executemany('INSERT INTO numbers (num) VALUES (?)', values())
except sqlite3.DatabaseError, err:
print u'Error: ', err
else:
con.commit()
print u'Number of added rows: %d' % cur.rowcount
cur.close()
con.close()
Бежит сценарий три раза. Последний раз с разными значениями() вывода, например, xrange (3,5). Таким образом, мы получаем выход
Number of added rows: 2
Number of added rows: 0
Number of added rows: 2
Хорошо, тогда давайте проверим нашу базу данных и все, кажется, как это должно
$ sqlite3 db.sqlite3 'select rowid, * from numbers'
1|1
2|2
3|3
4|4
Затем попытайтесь создать базу данных с добавлением автоинкрементного псевдоним столбца системы RowId.
CREATE TABLE numbers (id INTEGER PRIMARY KEY AUTOINCREMENT, num INTEGER UNIQUE ON CONFLICT IGNORE);
Затем выполните то же самое, что указано выше, и проверьте строки.
$ sqlite3 db.sqlite3 'select rowid, * from numbers'
1|1|1
2|2|2
5|5|3 <- sqlite jumped over intermediate counter values for rowid and id column
6|6|4
SQLite сохраняет промежуточные значения счетчиков для ROWID и псевдоним столбца автоинкремента при использовании ИГНОРИРУЙТЕ ограничения алгоритм разрешения voilation для таблицы и пропускает их при назначении нового значения автоинкрементного. Зачем?