Форум сайта python.su
sqlite3
Первое поле Primary Key естественно оно уникальное и повторяться не должно.
После удаления записи нумерация сбивается и это вызывало ошибки в программе.
Как восстановить очередность primary key?
Я конечно сделал но по своему (в два прохода update), не оптимально а говнокодить то не хочется.
Поэтому спрашиваю как лучше сделать?.
Офлайн
Могу предположить что такие поля должны быть авто инкрементируемыми, наподобие того как устроен дефолтное id поле. Таким образом за счет средств самой БД оно будет всегда уникальным при создании новой записи.
Т.е. имеет место не правильное построение архитектуры программы и БД
Офлайн
Вот тут я вас не понял JOHN_16 при добавлении новых записей действительно primary key автоинкрементируется а вот при удалении записей последовательная нумерация не восстанавливается. А что должна?
Офлайн
Если ваш софт рассчитывает на пронумерованность данных, то ошибки у вас прежде всего в проектировании. В таблицах реляционных бд данные неупорядочены, ключ должен быть уникальным и большего от него не требуется. Изменение данных первичного ключа вообще должно быть исключительным событием.
Офлайн
XoFfiCEr
нет и не должна восстанавливаться.
Офлайн
sqlite делает +1 для новой записи, а вот постгрес например ведет счетчик.
в разных субд по разному
Офлайн
Спасибо всем ответившим в этой теме.
Вот простая функция удаления записи из таблицы БД.
Вроде все ок…
def tab5_kill(): # процедура удаления кривой пути по идентификатору global tab5_editmode # глобальные переменные conn=sqlite3.connect(src_file) # подключение curs=conn.cursor() # готовимся к удалению curs.execute('delete from curves where id = ?', [tab5_id]) # непосредственно удаление conn.commit() # подтверждаем curs.close() # закрываем conn.close() # закрываем нах tab5_correct_id() # коррекция идентификаторов кривых sfile=src_file[ld:] # файл БД с которым мы работаем logtext='удалена кривая пути, база данных '+sfile # сообщение для log файла save_text_to_log_file(logtext) # записываем в log файл tab5_clear_text_fields() # очищаем поля ввода ибо нефиг tab5_editor_direction.config(text=xs[0])# возвращаем дефолтное направление кривой tab5_editmode=False # переход в режим добавления tab5_after_update() # обновление информации о кривых tabmode5_view() # переход на обработку tab5 notebook #tab5_service_message(2) # сообщение о выполнении
Офлайн
Очередность первичного ключа восстанавливать нельзя. Это же элементарно нарушит связь между таблицами, которые связаны по первичному ключу.
Офлайн
VadimK они у меня вроде никак не связаны.
Всем, нужна помощь в оптимизации этой процедуры
def tab5_correct_id(): # коррекция идентификаторов по tab5 (кривые пути) read_database_file() # перечитываем базу данных c=0 # это счетчик корректирвоок random.seed(594999) # это говнокод конечно еще и какой pw=random.randint(3, 7) # но хоть работает беспроблемно dv=pow(10, pw) # коэфициент conn=sqlite3.connect(src_file) # подключаем БД curs=conn.cursor() # курсор i=0 # обнуляем счетчик while i<crv_count: # цикл si=i+1 # на единицу больше чем счетчик si*=dv # умножаем на множитель во избежание неуникальных ключей t=cdata[i][0] # текущее значение curs.execute('update curves set id=? where id=?', [si, t]) # обновление c=c+curs.rowcount # количество записей затронутых обновлением conn.commit() # выполняем i+=1 # инкрементируем i=0 # обнуляем счетчик while i<crv_count: # цикл опять прогон по всем кривым si=i+1 # инкрементируем ибо начинается не с нуля вообще то sd=si*dv # умножаекм на множитель curs.execute('update curves set id=? where id=?', [si, sd]) # обновление c=c+curs.rowcount # количество обновленных conn.commit() # подтврждаем выполнение i+=1 # инкрементируем счетчик curs.close() # закрываем курсор conn.close() # закрываем sqlite подключение #print ('выполнено корректировок: ', c) # отладочная информация
Отредактировано XoFfiCEr (Сен. 26, 2016 20:28:40)
Офлайн
Ух, мосье знает толк в извращениях! Зачем вам вообще СУБД при таком подходе? Конкурентного доступа нет, связей нет, данных не вагон(если смело таблицу целиком перелопачиваете ), не проще засунуть все в список и пиклить его в файл?
Офлайн