yiisoft/yii2 · error · yii\base\NotSupportedException

yii\db\sqlite\QueryBuilder::addUnique is not supported by SQ

Error message

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

What it means

yii\db\sqlite\QueryBuilder::addUnique() unconditionally throws NotSupportedException: SQLite cannot add a UNIQUE constraint to an existing table with ALTER TABLE. Unique indexes (CREATE UNIQUE INDEX) are supported, but the named-constraint API is not, so Yii rejects the operation outright.

Source

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

    /**
     * Builds a SQL statement for removing a primary key constraint to an existing table.
     * @param string $name the name of the primary key constraint to be removed.
     * @param string $table the table that the primary key constraint will be removed from.
     * @return string the SQL statement for removing a primary key constraint from an existing table.
     * @throws NotSupportedException this is not supported by SQLite
     */
    public function dropPrimaryKey($name, $table)
    {
        throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');
    }

    /**
     * {@inheritdoc}
     * @throws NotSupportedException this is not supported by SQLite.
     */
    public function addUnique($name, $table, $columns)
    {
        throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');
    }

    /**
     * {@inheritdoc}
     * @throws NotSupportedException this is not supported by SQLite.
     */
    public function dropUnique($name, $table)
    {
        throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');
    }

    /**
     * {@inheritdoc}
     * @throws NotSupportedException this is not supported by SQLite.
     */
    public function addCheck($name, $table, $expression)
    {
        throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. On sqlite, create a unique index instead: $this->createIndex('uq_name', 'tbl', 'email', true).
  2. Branch on $this->db->driverName === 'sqlite' in the migration.
  3. Declare UNIQUE inline in the original CREATE TABLE for sqlite-first schemas.
  4. Catch NotSupportedException in driver-agnostic runners.

Example fix

// before
$this->addUnique('uq_user_email', 'user', ['email']);

// after
if ($this->db->driverName !== 'sqlite') {
    $this->addUnique('uq_user_email', 'user', ['email']);
} else {
    $this->createIndex('uq_user_email', 'user', 'email', true); // UNIQUE index
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ($db->driverName !== 'sqlite') {
    $db->createCommand()->addUnique($name, $table, $columns)->execute();
} else {
    // SQLite equivalent: a UNIQUE index
    $db->createCommand()->createIndex($name, $table, $columns, true)->execute();
}

Try / catch

try {
    $db->createCommand()->addUnique($name, $table, $columns)->execute();
} catch (\yii\db\NotSupportedException $e) {
    // SQLite: fall back to CREATE UNIQUE INDEX
    $db->createCommand()->createIndex($name, $table, $columns, true)->execute();
}

Prevention

When it happens

Trigger: A migration calling $this->addUnique('uq_name', 'tbl', ['email']) or the equivalent Command call while the connection is sqlite - commonly the test/CI database.

Common situations: Cross-driver migrations adding unique constraints after table creation; sqlite in-memory test databases running the full migration set; schema-tidying migrations written for production MySQL/PostgreSQL.

Related errors


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