phalcon/cphalcon · error · SqliteAlterPrimaryKeyNotSupported
Adding a primary key after table has been created is not sup
Error message
Adding a primary key after table has been created is not supported by SQLite
What it means
The SQLite dialect's addPrimaryKey() always throws SqliteAlterPrimaryKeyNotSupported. SQLite's ALTER TABLE cannot add a PRIMARY KEY after a table exists; the key must be declared in the original CREATE TABLE column/table definition. The dialect throws immediately instead of producing SQL the engine would reject.
Source
Thrown at phalcon/Db/Dialect/Sqlite.zep:141
let sql .= "\"" . index->getName() . "\"";
}
let sql .= " ON \"" . tableName . "\" ("
. this->getIndexColumnList(index, false) . ")";
if index->getWhere() !== "" {
let sql .= " WHERE " . index->getWhere();
}
return sql;
}
/**
* Generates SQL to add the primary key to a table
*/
public function addPrimaryKey( string tableName, string schemaName, <IndexInterface> index) -> string
{
throw new SqliteAlterPrimaryKeyNotSupported();
}
/**
* Generates SQL to create a table
*/
public function createTable( string tableName, string schemaName, array definition) -> string
{
var columns, table, temporary, options, createLines, columnLine,
column, indexes, index, indexName, indexType, references, reference,
defaultValue, referenceSql, onDelete, onUpdate, checks, check;
bool hasPrimary;
string sql;
let table = this->prepareTable(tableName, schemaName);
let temporary = false;
if fetch options, definition["options"] {
fetch temporary, options["temporary"];View on GitHub (pinned to b7419de9cd)
Solutions
- Declare the primary key at creation: new Column('id', ['type' => Column::TYPE_INTEGER, 'primary' => true]) or the 'primary' key in the table definition's indexes
- For an existing table use the SQLite table-rebuild procedure (new table with PK, copy data, drop, rename)
- Skip the call on SQLite: if (!($adapter->getDialect() instanceof Sqlite)) { $adapter->addPrimaryKey(...); }
Example fix
// before
$connection->addPrimaryKey('robots', null, new Index('PRIMARY', ['id']));
// after — PK at CREATE TABLE time on SQLite
$connection->createTable('robots', null, [
'columns' => [
new Column('id', ['type' => Column::TYPE_INTEGER, 'primary' => true]),
],
]); Defensive patterns
Strategy: type-guard
Validate before calling
if ($adapter->getDialect() instanceof \Phalcon\Db\Dialect\Sqlite) {
throw new RuntimeException('SQLite: declare the primary key in createTable(), not addPrimaryKey()');
}
$adapter->addPrimaryKey($table, $schema, $index); Type guard
function supportsAddPrimaryKey(\Phalcon\Db\Adapter\AdapterInterface $adapter): bool
{
return !($adapter->getDialect() instanceof \Phalcon\Db\Dialect\Sqlite);
} Try / catch
try {
$adapter->addPrimaryKey($table, $schema, $index);
} catch (\Phalcon\Db\Exceptions\SqliteAlterPrimaryKeyNotSupported $e) {
rebuildSqliteTableWithPrimaryKey($adapter, $table, $index);
} Prevention
- Mark the primary key on the Column ('primary' => true) at CREATE TABLE time for SQLite
- Avoid migration generators that split primary-key creation into a later ALTER step
- Test the full migration chain on every adapter you support
When it happens
Trigger: Calling $sqliteAdapter->addPrimaryKey('robots', null, $index) — typically from generated migrations that create the table first and add its primary key in a later step; running those migrations against SQLite in tests or local dev.
Common situations: Migration generators that split primary-key creation into a separate ALTER step (valid on MySQL/PostgreSQL); adapting production migrations to SQLite-backed test environments.
Related errors
- Adding a CHECK constraint to an existing table is not suppor
- Adding a foreign key constraint to an existing table is not
- Removing a primary key after table has been created is not s
- The table must contain at least one column
- The index 'columns' is required in the definition array
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/7668688149c41c40.
Report an issue: GitHub.