Skip to content

Conversation

@guvra
Copy link

@guvra guvra commented Dec 23, 2025

Fixes #1830

This PR adds foreign key support for SQLite dialect (cf. https://sqlite.org/foreignkeys.html for specification).

Changes

The following code now successfully creates a foreign key with sqlite:

return new CreateTableStatement('books')
    ->primary()
    ->belongsTo('books.author_id', 'authors.id', OnDelete::CASCADE)
    ->text('title');

At first, it didn't work because in SQLite, foreign keys must be defined after table columns.

So I used the sortByCallback function on the statements array in order to make sure that foreign keys are always defined at the end of the create table statement.

Limitations

The following code fails (QueryWasInvalid exception):

public function up(): QueryStatement
{
    return new AlterTableStatement('authors')
        ->add(new BelongsToStatement('books.author_id', 'authors.id', OnDelete::CASCADE));
}

This is perfectly normal because it is not possible to add a foreign key on an existing table in sqlite.

It would be better if tempest threw a DialectWasNotSupported exception, but I'm not sure if it's possible to implement easily, because the BelongsToStatement is wrapped inside a AlterAddColumnStatement object.

Warning

I updated the unit tests but I didn't do a lot of real world testing.
I only tested a migration with a create statement and an alter statement.

@guvra guvra force-pushed the feat-sqlite-foreign-keys branch from 4856af1 to 5c7c3c5 Compare December 24, 2025 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Database] Support foreign keys with sqlite dialect

1 participant