Migrate fresh fails when SQLite database is on WAL mode #53044
Replies: 2 comments 1 reply
-
@renatofrota This behavior is likely happening because the connection is reused, and some SQLite operations like dropping tables or transactions might revert the Solution to Ensure
|
Beta Was this translation helpful? Give feedback.
-
Thank you, @vjaykoogu, for suggesting ways to circumvent the issue. However, the existence of them does not mean this is not something to be fixed in Laravel, @crynobone. Please consider my arguments. No commands can make the journal_mode to change, except an explicit call to statement I have traced down the problem to /**
* Drop all tables from the database.
*
* @return void
*/
public function dropAllTables()
{
if ($this->connection->getDatabaseName() !== ':memory:') {
return $this->refreshDatabaseFile();
}
$this->connection->select($this->grammar->compileEnableWriteableSchema());
$this->connection->select($this->grammar->compileDropAllTables());
$this->connection->select($this->grammar->compileDisableWriteableSchema());
$this->connection->select($this->grammar->compileRebuild());
}
/**
* Empty the database file.
*
* @return void
*/
public function refreshDatabaseFile()
{
file_put_contents($this->connection->getDatabaseName(), '');
} The 2nd method above (called by the first) replaces all the The command that would be run if it were a memory database: $sqlite3 database/database.sqlite
sqlite> pragma writable_schema=1;
sqlite> delete from sqlite_master where type in ('table', 'index', 'trigger');
sqlite> pragma writable_schema=0;
sqlite> vacuum;
sqlite> pragma journal_mode;
wal The last command above is a query to the journal_mode (to confirm it does not change from wal to delete). And after running these manually, So, IMHO, it's a Laravel bug. Why not proceed with this regular way to empty the database, in a safe way (keeping the file headers), as it is done to the SQLite databases running in memory? |
Beta Was this translation helpful? Give feedback.
-
Laravel Version
11.26.0
PHP Version
8.3.12
Database Driver & Version
SQLite 3.37.2
Description
Apparently, Laravel reuses the same SQLite connection to drop all tables and then perform migrations. Somewhere in the process, the journal_mode defaults to 'delete'. If the database was previously in 'wal' mode, the commands to populate the database will fail. On a retry, it succeeds (however, the journal_mode defaults back to 'delete' without notifying the user).
Steps To Reproduce
Install Laravel and select SQLite as database
Connect to the database and set Journal Mode to WAL (Write Ahead Log)
Now, try migrate:fresh. It fails on first attempt.
Succeeds in the subsequent attempt.
Beta Was this translation helpful? Give feedback.
All reactions