Какова команда для удаления всех таблиц в SQLite?
Аналогично, я хотел бы удалить все индексы.
Какова команда для удаления всех таблиц в SQLite?
Аналогично, я хотел бы удалить все индексы.
rm db/development.sqlite3
Я не думаю, что вы можете удалить все таблицы одним ударом, но вы можете сделать следующее, чтобы получить команды:
select 'drop table ' || name || ';' from sqlite_master
where type = 'table';
Результатом этого является script, который выведет таблицы для вас. Для индексов просто замените таблицу индексом.
Вы можете использовать другие предложения в разделе where
, чтобы ограничить, какие таблицы или индексы выбраны (например, "and name glob 'pax_*'
" для тех, кто начинается с "pax _" ).
Вы могли бы объединить создание этого script с его запуском в простом bash (или cmd.exe) script, так что будет работать только одна команда.
Если вы не заботитесь о любой информации в БД, я думаю, вы можете просто удалить файл, который он хранит на жестком диске, - что, вероятно, быстрее. Я никогда не тестировал это, но я не понимаю, почему это не сработает.
Хотя верно, что нет команды DROP ALL TABLES, вы можете использовать следующий набор команд.
Примечание. Эти команды могут повредить вашу базу данных, поэтому убедитесь, что у вас есть резервная копия
PRAGMA writable_schema = 1;
delete from sqlite_master where type in ('table', 'index', 'trigger');
PRAGMA writable_schema = 0;
вы хотите восстановить удаленное пространство с помощью
VACUUM;
и хороший тест, чтобы убедиться, что все в порядке
PRAGMA INTEGRITY_CHECK;
У меня была такая же проблема с SQLite и Android. Вот мое решение:
List<String> tables = new ArrayList<String>();
Cursor cursor = db.rawQuery("SELECT * FROM sqlite_master WHERE type='table';", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String tableName = cursor.getString(1);
if (!tableName.equals("android_metadata") &&
!tableName.equals("sqlite_sequence"))
tables.add(tableName);
cursor.moveToNext();
}
cursor.close();
for(String tableName:tables) {
db.execSQL("DROP TABLE IF EXISTS " + tableName);
}
Я хотел бы добавить к другим ответам, связанным с отбрасыванием таблиц и не удалять файл, чтобы вы также могли выполнять последовательности delete from sqlite_sequence
до reset с автоматическим приращением.
Использование pysqlite:
tables = list(cur.execute("select name from sqlite_master where type is 'table'"))
cur.executescript(';'.join(["drop table if exists %s" %i for i in tables]))
Как только вы отбросили все таблицы (и индексы исчезнут, когда эта таблица идет), тогда в базе данных SQLite ничего не осталось, насколько я знаю, хотя файл, похоже, не сокращается (из быстрого теста Я только что сделал).
Таким образом, удаление файла будет самым быстрым - его нужно просто воссоздать, когда ваше приложение попытается получить доступ к файлу db.
У меня была эта проблема в Android, и я написал метод, аналогичный этому - запад.
Поскольку я использовал первичные ключи AUTOINCREMENT
в своих таблицах, была таблица с именем sqlite_sequence
. SQLite зависнет, когда подпрограмма попытается удалить эту таблицу. Я не мог поймать исключение либо. Глядя на https://www.sqlite.org/fileformat.html#internal_schema_objects, я узнал, что может быть несколько таких таблиц внутренней схемы, которые я не хотел отбрасывать. В документации сказано, что у каждой из этих таблиц есть имена, начинающиеся с sqlite_, поэтому я написал этот метод
private void dropAllUserTables(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
//noinspection TryFinallyCanBeTryWithResources not available with API < 19
try {
List<String> tables = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
tables.add(cursor.getString(0));
}
for (String table : tables) {
if (table.startsWith("sqlite_")) {
continue;
}
db.execSQL("DROP TABLE IF EXISTS " + table);
Log.v(LOG_TAG, "Dropped table " + table);
}
} finally {
cursor.close();
}
}
Я не могу сказать, что это самое пуленепробиваемое или портативное решение, но оно работает для моих сценариев тестирования:
.output /tmp/temp_drop_tables.sql
select 'drop table ' || name || ';' from sqlite_master where type = 'table';
.output stdout
.read /tmp/temp_drop_tables.sql
.system rm /tmp/temp_drop_tables.sql
Этот фрагмент кода перенаправляет вывод во временный файл, создает команды "перетаскивания таблицы", которые я хочу выполнить (отправка команд во временный файл), возвращает вывод в стандартный вывод, затем выполняет команды из файла и, наконец, удаляет файл.
Или по приглашению оболочки, всего в двух строках, без именованного временного файла, предполагая, что $ db - это имя базы данных SQLite:
echo "SELECT 'DROP TABLE ' || name ||';' FROM sqlite_master WHERE type = 'table';" |
sqlite3 -readonly "$db" | sqlite3 "$db"