Skip to content
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

Consider redoing extensions, enums, ranges via ModelDiffer #730

Open
roji opened this issue Dec 2, 2018 · 7 comments
Open

Consider redoing extensions, enums, ranges via ModelDiffer #730

roji opened this issue Dec 2, 2018 · 7 comments
Assignees
Milestone

Comments

@roji
Copy link
Member

roji commented Dec 2, 2018

Our current support of PostgreSQL-specific database objects (extensions, enums, ranges, soon hopefully composites) is currently done purely via annotations - objects are represented as metadata on the model, which are then flowed into migrations via annotations on AlterDatabaseOperation. This is unlike EF Core's support for sequences, for example, which has metadata annotations (like us) but then picks up the sequences in the ModelDiffer, which then generates special {Create,Drop,Rename}SequenceOperation.

Our approach is problematic for the following reasons:

  • Addition/removal of objects needs to be done in our MigrationsSqlGenerator - compare old and new annotations on an AlterDatabaseOperation, calculate what was added, what was removed, etc. This work conceptually belongs in ModelDiffer rather than in MigrationsSqlGenerator.
  • It's impossible to implement correct DefaultSchema support, because we have no way of knowing that the DefaultSchema has changed, and that our database objects need to be moved accordingly (see Schema enums follow up (part 2) #685 (comment)).

In the past, we already have a discussion about providing our own ModelDiffer, which would generate custom migration operations (e.g. CreateEnumOperation). This would be a better design and align us with the way EF Core does things. It may be worth revisiting for 3.0 in case we change our minds.

/cc @austindrenski @ajcvickers @divega @bricelam

@roji roji added this to the 3.0.0 milestone Dec 2, 2018
@roji
Copy link
Member Author

roji commented Dec 5, 2018

Just a thought I had about this... Detecting changes in the ModelDiffer does not necessarily mean that we have to custom migrations for them. One of the previous main objections in dotnet/efcore#6524 was that custom migration operations would require generating code for them, in C# and potentially other languages, and that would become complicated.

However, at least in theory we can have our own ModelDiffer which finds the appropriate differences between enums, ranges and extensions, but then represents the appropriate operations to be done again, as annotations on an AlterDatabase migration. In other words, instead of flowing model metadata annotations directly to the migrations, they'd be picked up in a special way in the ModelDiffer, which would translate them to other annotations that represent actual operations that need to take place. This would imply some sort of scheme for representing "change this enum in this way" via an annotation on AlterDatabase, which isn't trivial but probably doable.

Just recording some thoughts here for when we get around to revisiting this...

@austindrenski
Copy link
Contributor

I'm starting to look into this today. It has some potential overlap with #736, but I think it makes sense to start here since may require upstream refactoring (e.g. changing the namespace on
MigrationsModelDiffer), so probably best to identify those changes sooner rather than later.

@austindrenski austindrenski self-assigned this Dec 10, 2018
@roji
Copy link
Member Author

roji commented Dec 10, 2018

OK. I'd recommend not going too far into this without showing an approach we can discuss, to make sure we all agree on where we're going etc.

@austindrenski
Copy link
Contributor

Sounds good, I'll open a PR once I have something basic put together.

@bricelam
Copy link
Contributor

bricelam commented Jan 2, 2019

I'm sad you have to resort to replacing the model differ. I feel like making the core/relational model more extensible (beyond our current annotations mechanism) would be a better solution to the problem. Making schemas more first-class might help too.

In other words, I don't think providers should have to change the model differ, but if they add new concepts to the model, they should be able to define how they get diffed. This is the current approach with model annotations, but it's limited by the fact that annotations are simple key-value pairs and they force you have to perform structural diffing in during SQL generation.

@austindrenski
Copy link
Contributor

austindrenski commented Jan 2, 2019

@bricelam Having better schema support throughout the model would be great, and defining configurations without wading into the model differ itself would be nice too.

All things considered, the changes in #744 seem pretty narrow (to me, that is), but I can understand the hesitation to have providers wading into the model differ for every change.

I could imagine implementing the changes in #744 following the pattern that we currently use for CompositeMethodCallTranslator, but I'm not sure what type of changes that would require from the core project.

@bricelam
Copy link
Contributor

bricelam commented Jan 2, 2019

Oh, and I'm certainly not pushing back on having Npgsql override it (the changes we made in EF Core 2.0 make it safe to do). It's just something that providers shouldn't ever have to override so when they do, it's a good sign we're missing extensiblity points elsewhere.

@roji roji modified the milestones: 3.0.0, Backlog Aug 24, 2019
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 a pull request may close this issue.

3 participants