phalcon/cphalcon · error · Phalcon\Db\Exceptions\SqliteDropPrimaryKeyNotSupported

Removing a primary key after table has been created is not s

Error message

Removing a primary key after table has been created is not supported by SQLite

What it means

Phalcon\Db\Dialect\Sqlite::dropPrimaryKey() always throws SqliteDropPrimaryKeyNotSupported. In SQLite the primary key is fixed in the CREATE TABLE definition; there is no ALTER TABLE ... DROP PRIMARY KEY statement, so removing it after creation is impossible without rebuilding the table.

Source

Thrown at phalcon/Db/Dialect/Sqlite.zep:394

    /**
     * Generates SQL to delete an index from a table
     */
    public function dropIndex( string tableName,  string schemaName,  string indexName) -> string
    {
        if schemaName {
            return "DROP INDEX \"" . schemaName . "\".\"" . indexName . "\"";
        }

        return "DROP INDEX \"" . indexName . "\"";
    }

    /**
     * Generates SQL to delete primary key from a table
     */
    public function dropPrimaryKey( string tableName,  string schemaName) -> string
    {
        throw new SqliteDropPrimaryKeyNotSupported();
    }

    /**
     * Generates SQL to drop a table
     */
    public function dropTable( string tableName, string schemaName = null,  bool ifExists = true) -> string
    {
        var table;

        let table = this->prepareTable(tableName, schemaName);

        if ifExists {
            return "DROP TABLE IF EXISTS " . table;
        }

        return "DROP TABLE " . table;
    }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Skip the operation when $connection->getDialectType() === 'sqlite'
  2. Rebuild the table without PRIMARY KEY (create new, copy, drop old, rename) if the key must really go
  3. Restructure the migration so primary key changes ship as a new table definition rather than an ALTER step

Example fix

// before
$connection->dropPrimaryKey('posts', null);

// after
if ($connection->getDialectType() !== 'sqlite') {
    $connection->dropPrimaryKey('posts', null);
}
// on SQLite, recreate the table without PRIMARY KEY if required
Defensive patterns

Strategy: try-catch

Validate before calling

if ($connection->getDialectType() !== 'sqlite') {
    $connection->dropPrimaryKey('posts', null);
}

Try / catch

try {
    $connection->dropPrimaryKey('posts', null);
} catch (\Phalcon\Db\Exceptions\SqliteDropPrimaryKeyNotSupported $e) {
    // SQLite: primary key is fixed at CREATE TABLE; rebuild if it must change
    $logger->info('Skipped dropPrimaryKey on SQLite', ['table' => 'posts']);
}

Prevention

When it happens

Trigger: Migration code calling $connection->dropPrimaryKey('posts', null) while the connection uses the Sqlite dialect; schema-normalization steps that strip primary keys on every supported database.

Common situations: Cross-dialect migrations; SQLite test databases exercising MySQL-oriented migration sets; tools that regenerate primary keys by drop-and-add, which works on MySQL but not SQLite.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/e0ffe1ba9d24357e. Report an issue: GitHub.