yiisoft/yii2 · error · yii\base\NotSupportedException

yii\db\sqlite\QueryBuilder::dropForeignKey is not supported

Error message

yii\db\sqlite\QueryBuilder::dropForeignKey is not supported by SQLite.

What it means

yii\db\sqlite\QueryBuilder::dropForeignKey() unconditionally throws NotSupportedException because SQLite's ALTER TABLE has no DROP CONSTRAINT/DROP FOREIGN KEY form - foreign keys are part of the CREATE TABLE definition. Any migration that drops an FK while running on SQLite hits this.

Source

Thrown at framework/db/sqlite/QueryBuilder.php:311

     * @param string|null $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
     * @return string the SQL statement for adding a foreign key constraint to an existing table.
     * @throws NotSupportedException this is not supported by SQLite
     */
    public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null)
    {
        throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');
    }

    /**
     * Builds a SQL statement for dropping a foreign key constraint.
     * @param string $name the name of the foreign key constraint to be dropped. The name will be properly quoted by the method.
     * @param string $table the table whose foreign is to be dropped. The name will be properly quoted by the method.
     * @return string the SQL statement for dropping a foreign key constraint.
     * @throws NotSupportedException this is not supported by SQLite
     */
    public function dropForeignKey($name, $table)
    {
        throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');
    }

    /**
     * Builds a SQL statement for renaming a DB table.
     *
     * @param string $table the table to be renamed. The name will be properly quoted by the method.
     * @param string $newName the new table name. The name will be properly quoted by the method.
     * @return string the SQL statement for renaming a DB table.
     */
    public function renameTable($table, $newName)
    {
        return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' RENAME TO ' . $this->db->quoteTableName($newName);
    }

    /**
     * Builds a SQL statement for changing the definition of a column.
     * @param string $table the table whose column is to be changed. The table name will be properly quoted by the method.
     * @param string $column the name of the column to be changed. The name will be properly quoted by the method.

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Guard the migration per driver: skip dropForeignKey() when $this->db->driverName === 'sqlite'.
  2. Apply SQLite's only real path: recreate the table without the FK and copy the data.
  3. Catch NotSupportedException in cross-DB migration runners and mark the step skipped.
  4. Design migrations to keep FK changes at CREATE TABLE time for sqlite deployments.

Example fix

// before
$this->dropForeignKey('fk_order_user', 'order');

// after
if ($this->db->driverName !== 'sqlite') {
    $this->dropForeignKey('fk_order_user', 'order');
} else {
    // SQLite: rebuild table without the FK, copy data, swap names
    $this->execute('CREATE TABLE order_new ... ; INSERT INTO order_new SELECT * FROM "order"; DROP TABLE "order"; ALTER TABLE order_new RENAME TO "order";');
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ($db->driverName !== 'sqlite') {
    $db->createCommand()->dropForeignKey($name, $table)->execute();
} else {
    // SQLite: rebuild table without FK, or skip in tests
}

Try / catch

try {
    $db->createCommand()->dropForeignKey($name, $table)->execute();
} catch (\yii\db\NotSupportedException $e) {
    // SQLite cannot drop FK constraints; rebuild the table or skip
}

Prevention

When it happens

Trigger: Executing $this->dropForeignKey('fk_name', 'tbl') in a migration, or calling $db->createCommand()->dropForeignKey(...), when the connection's driver is sqlite - e.g., an in-memory or file test database.

Common situations: Test suites configured with sqlite for speed while migrations were written for MySQL/PostgreSQL; CI pipelines running the whole migration chain on sqlite; down() migrations dropping FKs.

Related errors


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/e568fac48ce2b6bc. Report an issue: GitHub.