How do you safely add a non-nullable column in sqflite?
Tests onCreate for fresh installs vs onUpgrade for existing data. Outline: bump version; in onUpgrade use ALTER TABLE ADD COLUMN NOT NULL DEFAULT for existing rows; keep onCreate as latest schema. Red flag: only changing onCreate so old users crash.
What's really being asked
This question tests whether you understand the lifecycle of a local SQLite database in Flutter and the strict separation between creating a schema for new users versus migrating data for existing users. It also checks your knowledge of SQLite ALTER TABLE semantics, specifically that adding a NOT NULL column to a table that already contains rows is only safe if you supply a DEFAULT value. Interviewers want to see that you think about data durability and versioned, incremental migrations rather than destructive rebuilds.
The full answer
First, increment the database version integer passed to openDatabase so that the framework knows a migration is required. Second, explain that onCreate is only invoked when the database file does not exist; inside it you should execute the full latest CREATE TABLE statement including the new non-nullable column so fresh installs never run migrations. Third, describe onUpgrade as the path for existing users; here you execute an ALTER TABLE ADD COLUMN statement that includes both NOT NULL and a DEFAULT value, which lets SQLite populate existing rows safely without data loss. Fourth, mention wrapping the migration in a batch or transaction so the upgrade is atomic; if any step fails the database rolls back and the app does not end up in a half-migrated state. Fifth, note that you should structure onUpgrade with a switch or cascading if statements on oldVersion so that users jumping multiple versions are handled correctly.
The mistakes people make
A major red flag is editing onCreate to add the column while leaving onUpgrade empty; this works for new installs but crashes existing users because their old schema never gets updated. Another red flag is dropping the existing table and recreating it without first copying data out; that destroys user data. Some candidates suggest adding the column with NOT NULL but omitting DEFAULT; on a non-empty table SQLite rejects this and the app crashes. Finally, failing to bump the version number means neither callback fires and every user stays on the old schema.
What usually comes next
The interviewer might ask how you would handle a migration that is too complex for ALTER TABLE, such as adding a foreign key or splitting a column into two; the correct pattern is create a new table, copy data with transformations, drop the old table, and rename. They may also ask how you test migrations; the robust approach is to keep a set of schema-versioned database files, open them with the new code, and assert the final schema and data. Another follow-up is downgrades; sqflite offers onDowngrade, and the safest default is often onDatabaseDowngradeDelete, though that wipes data so you must warn users.
A concrete example
Imagine a todo app where version 1 has a Task table with id and title. In version 2 you need a priority integer that cannot be null and defaults to zero. You set version to 2. In onCreate you run CREATE TABLE Task id INTEGER PRIMARY KEY, title TEXT, priority INTEGER NOT NULL DEFAULT 0. In onUpgrade when oldVersion is 1 you run ALTER TABLE Task ADD COLUMN priority INTEGER NOT NULL DEFAULT 0 inside a batch commit. Existing tasks all get priority zero, new tasks must supply a value, and no data is lost.
Interview question
You must add a required column with a default to a sqflite table that already has rows. Which approach safely handles both new installs and existing users?
- a.Keep the database version unchanged, add the column to onCreate, and leave onUpgrade empty because existing schemas do not need updates.
- b.Bump the version, drop the existing table in onUpgrade, recreate it with the new column, and rely on onCreate for fresh installs.
- c.Bump the version, update onCreate with the new column, and run ALTER TABLE ADD COLUMN with NOT NULL but without a DEFAULT in onUpgrade.
- d.Bump the version, update onCreate with the new column, and run ALTER TABLE ADD COLUMN with NOT NULL and a DEFAULT value in onUpgrade.Correct
Why? this is the answer
Option D is correct because it triggers onUpgrade via a version bump, preserves the latest schema in onCreate for new users, and supplies a DEFAULT value so SQLite can populate existing rows safely. Option C is the most tempting distractor because it correctly identifies the version bump and dual-path approach but omits the DEFAULT, causing SQLite to reject the alteration on non-empty tables and crash the app.
Just read this? Test yourself on what you have been reading.
Read the original → github.com
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on flutter — each one lists the topics its interview covers.
See open roles