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.

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.

Appendix: 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)