SQLite. Изменение таблицы без потери данных

Cегодня столкнулся с тем, что нужно было изменить уже созданные таблицы в базе данных SQLite. Поскольку понтовых менеждеров под рукой у меня нет, да я и не знаю об их существовании, пришлось все делать ручками, по старинке.

Для того, чтобы было понятно, что нужно было делать, приведу пример. Дана таблица, созданная следующим образом:

CREATE TABLE A (pk INTEGER PRIMARY KEY, name TEXT, cnt INTEGER);

А теперь мы решили сделать поле count NOT NULL. Вопрос: как изменить таблицу «А» без потери данных?

Я нашел только «ручной» и «муторный» способ. Он заключается в следующем: создаем буферную таблицу temp1 нужным нам образом, т.е. как

CREATE TABLE temp1 (pk INTEGER PRIMARY KEY, name TEXT, cnt INTEGER NOT NULL);

и перегоняем в нее данные через

INSERT INTO temp1 SELECT * FROM A;

После этого можно удалить таблицу «А»:

DROP TABLE A;

И переименовать temp в «A»:

ALTER TABLE temp1 RENAME TO A;

Вроде бы все хорошо, но что делать, если в исходной таблице в нужном поле все-таки были значения NULL? Ведь тогда новая таблица останется пустой! (У меня кстати и никакого сообщения об ошибке не было – просто транзакция не проходила. Молча.)

Я нашел решение в создании еще одной буферной таблицы «temp2» с заданным для изменяемого поля значением по умолчанию. Создавалась она как:

CREATE TABLE temp2 (pk INTEGER PRIMARY KEY, name TEXT, cnt INTEGER NOT NULL DEFAULT 0);

Соответственно, теперь нужно перегнать данные из таблицы А сначала в «temp2», где некорректные строчки превратятся в «подходящие», а уже потом в «temp1». После этого опять занимаемся переименованием последней :). Да, некоторые стоки данных изменятся, но зато основная информация сохранится. Естественно, хорошо бы не забыть удалить уже две лишние таблицы («А», и «temp2»).

Аналогичным образом можно поступить, если нужно будет добавить новое поле в таблицу, только INSERT в новую таблицу делать уже конкретных полей, а SELECT – по всей таблице.

P.S.: Наверняка, я изобрел свой велосипед с квадратными колесами, поэтому буду рад услышать, как выглядят «классические» решения для этих задач, если кто знает. А может даже и об удобных менеджерах для SQLite, чтобы не делать в следующий раз все «ручками».

Полезная статья? Их будет больше, если вы поддержите меня!

https://money.yandex.ru/embed/small.xml?account=410011399843532&quickpay=small&yamoney-payment-type=on&button-text=06&button-size=l&button-color=orange&targets=%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%B2%D0%B0%D1%8E+%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82+lexpenz.com&default-sum=50&successURL=

Архив комментариев

2 комментария из прежней версии блога. Архив закрыт для новых ответов.

  1. Есть такая прога «SqliteDog», удобна редактировать базу. Правда я не очень пользовался и сайт тоже не помню.

  2. Спасибо за инфу — помогла.

    По вопросу об удобном менеджере — мне весьма понравилась SQLiteStudio http://sqlitestudio.pl