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

Altering a DB column is not supported by SQLite

Error message

Altering a DB column is not supported by SQLite

What it means

Phalcon\Db\Dialect\Sqlite::modifyColumn() always throws SqliteAlterColumnNotSupported. SQLite offers no ALTER TABLE ... MODIFY/ALTER COLUMN statement — changing a column's type or size requires the create-new-table / copy / drop / rename procedure — so the dialect refuses rather than emitting invalid SQL.

Source

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

    public function listTables(string schemaName = null) -> string
    {
        return "SELECT tbl_name FROM sqlite_master WHERE type = 'table' ORDER BY tbl_name";
    }

    /**
     * Generates the SQL to list all views of a schema or user
     */
    public function listViews( string schemaName = null) -> string
    {
        return "SELECT tbl_name FROM sqlite_master WHERE type = 'view' ORDER BY tbl_name";
    }

    /**
     * Generates SQL to modify a column in a table
     */
    public function modifyColumn( string tableName,  string schemaName, <ColumnInterface> column, <ColumnInterface> currentColumn = null) -> string
    {
        throw new SqliteAlterColumnNotSupported();
    }

    /**
     * Appends a `RETURNING` clause to the supplied INSERT/UPDATE/DELETE
     * statement. Supported by SQLite 3.35+. Pass `["*"]` for `RETURNING *`,
     * or a list of column names.
     */
    public function returning( string sqlQuery,  array columns) -> string
    {
        var first;

        if unlikely empty columns {
            throw new ReturningRequiresColumn();
        }

        if count(columns) == 1 {
            let first = (string) columns[0];

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Branch on $connection->getDialectType() === 'sqlite' and use the rebuild procedure instead
  2. Rebuild: CREATE TABLE posts_new with the modified column, INSERT INTO posts_new SELECT * FROM posts, DROP TABLE posts, ALTER TABLE posts_new RENAME TO posts
  3. Batch incompatible column changes into one rebuild per table to avoid repeated copies

Example fix

// before
$connection->modifyColumn('posts', null, new Column('title', ['type' => Column::TYPE_VARCHAR, 'size' => 500]));

// after
if ($connection->getDialectType() === 'sqlite') {
    $connection->execute('CREATE TABLE posts_new (...)');
    $connection->execute('INSERT INTO posts_new SELECT * FROM posts');
    $connection->execute('DROP TABLE posts');
    $connection->execute('ALTER TABLE posts_new RENAME TO posts');
} else {
    $connection->modifyColumn('posts', null, new Column('title', ['type' => Column::TYPE_VARCHAR, 'size' => 500]));
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ($connection->getDialectType() === 'sqlite') {
    // rebuild: create posts_new with the modified column, copy, drop, rename
} else {
    $connection->modifyColumn('posts', null, $newColumn);
}

Try / catch

try {
    $connection->modifyColumn('posts', null, $newColumn);
} catch (\Phalcon\Db\Exceptions\SqliteAlterColumnNotSupported $e) {
    // SQLite has no ALTER COLUMN; run the table-rebuild procedure instead
    rebuildSqliteTable($connection, 'posts', $newDefinition);
}

Prevention

When it happens

Trigger: Generic migration code calling $connection->modifyColumn('posts', null, new Column('title', ['type' => Column::TYPE_VARCHAR, 'size' => 500])) against a SQLite connection; migration sets written against MySQL being replayed on SQLite in tests.

Common situations: Dev/test environments on SQLite while production runs MySQL/PostgreSQL; scaffolding tools generating uniform ALTER steps for every dialect; widening varchar columns — a routine MySQL migration that cannot map to SQLite.

Related errors


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