Deprecate overwriting existing foreign key constraints#7125
Conversation
10eac5c to
bb86c8c
Compare
|
status: needs work I think it's better to move that logic into the |
1d0aec6 to
f6f54de
Compare
|
status: needs review I ended up adding the logic to both Why did I do this? So why modify One possible solution could be to remove the Please let me know if this solution is incorrect or if any changes are needed. |
f6f54de to
09bc7da
Compare
|
Maybe I'm wrong, but I think the pipeline errors aren't related to this PR |
|
should this PR be targeting the 4.3.x branch instead? 🤔 |
Yes, this is unrelated. Sorry about the inconvenience.
That sounds right. You can change the base branch of this PR. |
09bc7da to
f62278a
Compare
|
Base branch changed to |
|
Hey! 👋 I saw this PR and went ahead and updated the tests to use |
64bae6c to
07d8eb8
Compare
|
@santysisi, thanks for the PR. Could you let us know whether it was prepared with the help of an AI tool, and if so, to what extent? This will helps us better understand how to approach reviewing it. |
|
Hi @morozov, thanks for your comment! Yes, I used an AI tool to help with writing comments (including PHPDoc) and to suggest some method and variable names. This comment is also written with the help of AI, as I'm still working on improving my English, and these tools help me communicate more clearly. Please let me know if there's anything you'd like me to revise. I'm happy to make changes! |
|
Hi @morozov, thanks a lot for taking the time to review the PR, I really appreciate it! 😊 If I understood correctly, the idea now is to trigger a deprecation notice only in case of a collision, but still continue with the current behavior (i.e., overwrite). If so, I can update the PR this weekend to reflect that behavior. Thanks again! ❤️ |
Correct. This will become an exception in 5.0.x. |
07d8eb8 to
7807eb3
Compare
7807eb3 to
fa759c8
Compare
|
Hi! 😄 |
fa759c8 to
5cedffd
Compare
morozov
left a comment
There was a problem hiding this comment.
We're getting close. Besides a few more comments, looks good.
5cedffd to
5cd827b
Compare
|
Thanks a lot for your suggestions, the changes have been made |
| Adding a foreign key constraint with a name that matches an existing one, whether explicitly specified or | ||
| auto-generated, has been deprecated. |
There was a problem hiding this comment.
Good question. In order to replace an existing constraint, drop it first via dropForeignKey().
@santysisi please add this to the upgrade notes.
Overwriting an existing foreign key constraint is now deprecated This behavior will no longer be allowed in Doctrine DBAL 5.0, where an exception will be thrown instead of silently overwriting the constraint.
5cd827b to
2e5dbaf
Compare
|
Thanks, @santysisi. Congrats on your first contribution! |
|
Thanks for your help! 😄 |
|
@santysisi, I merged the changes from this and your other PR up into |
|
Yep! 😄 Edit: I don't have enough time today 😔, I will try to do it this weekend |
|
Hi @morozov, While working on the new PR (to replace the deprecation with throw and error), I encountered an issue (reproducible with SQLite — I’ve tested with SQLite and PostgreSQL only so far) in this method getForeignKeysInAlteredTable. The problem stems from this change: #7116, specifically this part: Previously, we used unset($foreignKeys[$constraintName]), but since the method now returns a list, unsetting by key doesn’t work anymore. Before proceeding with the final deprecation removal and introducing the new error, I think we should address this issue first. I’d be happy to take a shot at fixing it! 😄 I see two possible approaches: Adjust the existing method: Introduce a new method: Let me know what you think! |
|
Just as an example — if we don’t want to introduce a new method that returns an associative array with constraint names as keys, we could handle it like this: $foreignKeys = [];
foreach ($oldTable->getForeignKeys() as $key => $foreignKey) {
$constraintName = $foreignKey->getObjectName();
if ($constraintName === null) {
$foreignKeys[$key] = $foreignKey;
continue;
}
$foreignKeys[strtolower($constraintName->getIdentifier()->getValue())] = $foreignKey;
}This way, we preserve the ability to reference foreign keys by their constraint names (like before), while still using the current method that returns a list. It’s a simple alternative to avoid breaking changes or adding a new method, instead of just doing: $foreignKeys = $oldTable->getForeignKeys();Another alternative could be a deeper refactor 🤔 |
Yeah, I noticed this issue as well. Indexing by name makes sense. The only thing is that your code still mixes name-based and positional keys, which is prone to conflicts ( Instead, you could introduce and populate a map of constraint names to their numeric keys in the
|
When multiple STI child entities have a ManyToOne relation to the same
target entity using the same join column, SchemaTool called
addForeignKeyConstraint twice with the same constraint name, triggering
a DBAL deprecation ("Overwriting an existing foreign key constraint").
The fix skips the redundant addForeignKeyConstraint call when an
identical FK (same local columns, same foreign table, same foreign
columns) was already added.
See doctrine/dbal#7125
When multiple STI child entities have a ManyToOne relation to the same
target entity using the same join column, SchemaTool called
addForeignKeyConstraint twice with the same constraint name, triggering
a DBAL deprecation ("Overwriting an existing foreign key constraint").
The fix skips the redundant addForeignKeyConstraint call when an
identical FK (same local columns, same foreign table, same foreign
columns) was already added.
See doctrine/dbal#7125
This PR introduces a deprecation notice when overwriting an existing foreign key constraint.
Summary