New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The SQLite3 adapter now implements the supports_deferrable_constraints?
contract
#49376
Conversation
Could the test failure be a flaky test? I can't reproduce locally and the error (
Could we retry the build? |
I've issued a rebuild. 🙏 Edit: The rebuild failed, but this test is also flaking on main. |
@zzak the fix for this flaky test is in main, can we rebuild this PR? |
@fractaledmind Could you rebase please? 🙇 |
d54697d
to
c85acbc
Compare
activerecord/test/cases/migration/references_foreign_key_test.rb
Outdated
Show resolved
Hide resolved
cb18ebd
to
a3e2c2b
Compare
a3e2c2b
to
38dd5f4
Compare
Would you address the |
…ts?` contract Implementing the full `supports_deferrable_constraints?` contract allows foreign keys to be deferred by adding the `:deferrable` key to the `foreign_key` options in the `add_reference` and `add_foreign_key` methods. ```ruby add_reference :person, :alias, foreign_key: { deferrable: :deferred } add_reference :alias, :person, foreign_key: { deferrable: :deferred } ```
38dd5f4
to
ea17941
Compare
@yahonda: Done (for both of my PRs) |
@@ -53,6 +53,16 @@ def indexes(table_name) | |||
end | |||
|
|||
def add_foreign_key(from_table, to_table, **options) | |||
if options[:deferrable] == true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rails main branch version is already 7.2.0.alpha, I'd like to keep this deprecation message as the PostgreSQL adapter does.
rails/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
Lines 526 to 528 in 2a986b7
ActiveRecord.deprecator.warn(<<~MSG) | |
`deferrable: true` is deprecated in favor of `deferrable: :immediate`, and will be removed in Rails 7.2. | |
MSG |
Motivation / Background
SQLite is a feature-rich database engine, and production usage is only growing. We need Rails' support to offer developers the range and scope of its features.
The PostgreSQL adapter supports deferred foreign keys, and SQLite itself has support deferred foreign keys since at least 2011.
Detail
Implementing the full
supports_deferrable_constraints?
contract allows foreign keys to be deferred by adding the:deferrable
key to theforeign_key
options in theadd_reference
andadd_foreign_key
methods.In this PR, I am adding full support for the SQLite3Adapter by implementing:
ActiveRecord::ConnectionAdapters::SQLite3::SchemaCreation#visit_AddForeignKey
ActiveRecord::ConnectionAdapters::SQLite3::SchemaCreation#visit_ForeignKeyDefinition
ActiveRecord::ConnectionAdapters::SQLite3Adapter#supports_deferrable_constraints?
ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements#assert_valid_deferrable
and altering:
ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements#add_foreign_key
ActiveRecord::ConnectionAdapters::SQLite3Adapter#foreign_keys
Additional Info
In order to get the
ActiveRecord::ConnectionAdapters::SQLite3Adapter#foreign_keys
method working properly, I had to add a query to get theCREATE TABLE
sql and parse which foreign key constraints are deferrable and which of those are deferred. In order to support this use-case, I extracted atable_structure_sql
method which nowtable_structure_with_collation
relies on.Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]