如何在不删除数据库文件的情况下完全清除SQLite3数据库?

时间:2014-02-04 08:43:35

标签: sql sqlite

对于单元测试目的,我需要完全重置/清除SQLite3数据库。运行测试套件时,所有数据库都在内存中而不是在文件系统上创建,因此我无法删除任何文件。另外,类的几个实例将同时引用数据库,因此我不能只在内存中创建一个新数据库并将其分配给变量。

目前我清理数据库的方法是从sqlite_master读取所有表名并删除它们。这与完全清除数据库不同,因为元数据和其他我不理解的东西可能会保留。

清除SQLite3数据库是否有一种干净简单的方法(如单个查询)?如果没有,那么必须对现有数据库进行哪些操作才能使其与全新的数据库完全相同?


如果它是相关的,我使用的是带有sqlite3-ruby版本1.3.7和SQLite3版本3.8.2的Ruby 2.0.0。

4 个答案:

答案 0 :(得分:3)

简单快捷的方法

如果使用内存数据库,最快,最可靠的方法是关闭并重新建立sqlite连接。它会刷新任何数据库数据以及每个连接设置。

如果你想要某种"重置"函数,你必须假设没有其他线程可以中断该函数 - 否则任何方法都将失败。因此,即使您有多个线程在该数据库上工作,也需要有一个"停止世界"互斥(或类似的东西),因此可以执行重置。虽然您可以独占访问数据库连接 - 为什么不关闭并重新打开它?

艰难的方式

如果存在其他一些限制而您无法按上述方式执行,那么您已经非常接近拥有完整的解决方案。如果你的线程没有明确地触摸pragma,那么只有" schema_version" pragma可以默默地更改,但如果你的线程可以改变pragma,那么你必须通过http://sqlite.org/pragma.html#toc上的列表并写'&34;重置"函数,它将每个pragma值设置为它的初始值(你需要在开始时读取默认值)。

注意,SQLite中的pragma可以分为3组:

  1. 最初定义,不可变或非常有限的可变性
  2. 动态定义,每个连接,可变
  3. 动态定义,每个数据库,可变
  4. 第1组是例如page_size,page_count,encoding等。这些是在数据库创建时刻定义的,而且以后不能修改常规,但有一些例外。例如,可以在" VACUUM"之前更改page_size,这样就可以设置新的页面大小。 page_count不能被用户更改,但在添加数据时会自动更改(显然)。编码在创建时定义,以后不能修改。 您不需要重置组1中的编译指示。

    组2例如是cache_size,recursive_triggers,jurnal_mode,foreign_keys,busy_timeout等。打开与数据库的新连接时,这些pragma始终设置为默认值。如果您没有断开连接,则需要手动将其重置为默认设置。

    组3例如是schema_version,user_version,也许还有其他一些,你需要查找它。那些还需要手动重置。如果从内存数据库断开连接,数据库就会被破坏,那么你就不需要重置它们了。

答案 1 :(得分:0)

SELECT * FROM dbname.sqlite_master WHERE type='table';

DROP TABLE

答案 2 :(得分:0)

  1. 创建一个空的内存数据库。
  2. 使用备份API将该数据库复制到实际数据库中。
  3. 对于sqlite3-ruby,请参阅test/test_backup.rb以获取示例。

答案 3 :(得分:0)

这在不删除文件和不关闭数据库连接的情况下工作:

PRAGMA writable_schema = 1;
DELETE FROM sqlite_master;
PRAGMA writable_schema = 0;
VACUUM;
PRAGMA integrity_check;

如果可能的话,另一种选择是使用 SQLITE_DBCONFIG_RESET_DATABASE

sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
sqlite3_exec(db, "VACUUM", 0, 0, 0);
sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);

这是reference