-
-
Notifications
You must be signed in to change notification settings - Fork 261
AutoMigrate for Postgres dialect #926
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
AutoMigrate for Postgres dialect #926
Conversation
|
I had to update a lot of to the existing unit tests (~5-7 files) because I noticed that many of them weren't properly cleaning up the database, causing side-effects in the auto-migrate tests. UPD: opened #927 for this specific change. Should make it easier to review the current one once the other changes are merged. |
* feat(schema): add support type for net/netip.Addr and net/netip.Prefix * fix(schema): net.IPNet(not ptr) is not implement fmt.Stringer Edit: updated commit message to comply with commitlint [subject-case] rule. Original subject: "Add support type..."
- RawQuery - CreateTableQuery
Additionally: - allow custom FK names (limited applicability rn) - implement GetReverse for AddFK and DropFK - detect renamed foreign keys - EqualSignature handles empty models (no columns)
This is a WIP commit.
- Do not implement AppendQuery on Operation level. This is a leaky abstraction as queries are dialect-specific and migrate package should not be concerned with how they are constructed. - AlterTableQuery also is an unnecessary abstraction. Now pgdialect will just build a simple string-query for each Operation. - Moved operations.go to migrate/ package and deleted alt/ package. - Minor clean-ups and documentation. testChangeColumnType is commented out because the implementation is missing.
Bufixes and improvements: - pgdialect.Inspector canonicalizes all default expressions (lowercase) to make sure they are always comparable with the model definition. - sqlschema.SchemaInspector canonicalizes all default expressions (lowercase) - pgdialect and sqlschema now support type-equivalence, which prevents unnecessary migrations like CHAR -> CHARACTER from being created. Changing PRIMARY KEY and UNIQUE-ness are outside of this commit's scope, because those constraints can span multiple columns.
FYI, identity is independent of primary keys and vice versa. It is only a method of generating new values for a column. Can be created and dropped in any order, as long as the column to add it to is declared NOT NULL
- New operations: AddColumn and DropColumn - Fixed cmpColumns to find 'extra' columns - Refactored alter query builder in pgdialect
Each dialect has to type-switch the operation before building a query for it. Since the migrator knows the concrete type of each operation, they are free to provide FQN in any form. Using schema.FQN field from the start simplifies the data structure later. Empty inteface is better that a superficial one.
Database inspector no longer mixes UNIQUE constraints with other constraint types, such as PK and FKs. While database drivers may require some FK and PK fields to be unique, these constraints are in practice distinct UNIQUE constraints and should not be synonymous to PK/FK constraints. Changes in UNIQUE constraints can be detected in any tables that haven't been dropped.
BaseFields -> BasePKs and JoinFields -> JoinPKs were updated in 8648d6f
AutoMigrator only supports 1 schema at a time. Use WithSchemaName() option to configure it. Defaults to the default schema in the dialect.
Now that AutoMigrator only works with one schema at a time, there's no need to keep the code which was used ot differentiate tables between schemas
|
Short update: we've decided to drop multi-schema support, so the user would instead configure AutoMigrator to work with a particular schema by passing |
|
Looks like we can now remove |
|
This looks pretty good. @bevzzz you should have necessary permissions to merge this so feel free to do it. |
|
@vmihailenco sorry, I've completely overlooked the last suggested changes. Will fix them in a follow-up PR, if that's alright with you. |
|
Hi. Thanks for this change. It looks like it will be useful. My use case is that I just wanted to generate and write out the migrations automatically, but not execute them at the same time. One piece of feedback regarding ordered.Map as a dependency: ordered map is very small. One small, simple file. The choice to use an internal type in exported fields of exported structs made this code unusable as is, and made extending and building upon it really really messy. I revisited this PR to see why that decision had been made when so many other types are fully exported. One other tiny issue that had cascading consequences: Anyone who uses WithForeignKeys in their tables instead of or in addition to relation tags will have those foreign keys dropped. Adding a WithForeignKeys AutoMigratorOption is a small change (a few lines of code) that would address that. I may submit a PR for that at some point. Also, it would be handy for migrate.comment to be an exported type. As it is, I had to use reflection to detect them. |
|
hi @bgrant0607
Fair point, no harm in exporting it, given all other operation types are exposed as well.
Can your use case be served by
Good point, I am going to look into that. Perhaps we could somehow push
|
|
@bevzzz I ran into multiple problems with the automigrate code and I was trying to build on it to work out solutions without forking all of bun. I reported two issues: #1159 and #1160. Another issue I had was that we have some tables with generated names that are managed separately, so I wanted to exclude tables based on a prefix or pattern. And I needed to be able to set the directory and the output filenames. The options weren't plumbed through CreateSQLMigrations and/or exported through options in a way I could use. I also had some issues with serializing multiple migration queries, like lack of semicolons and newlines IIRC, so I had to fork that part also to add the 2 characters. Maybe I was missing something from the pgdialect implementation. My diff of bun/migrate ended up being 1777 lines even though my changes were very minor. |
|
My patched version of WriteTo: |
|
Hmm. Looking at the current WriteTo code, I don't recall what problem I had with it now. |
I recall you also mentioned this, that working with an unexpected
That's a good idea. We can add
If you have the time to do it and the issue persists, would you care to post an MRE for me to look into? We do not any tests for this specifically, but it may be worth adding.
There's Line 79 in 04da1b6
which is the AutoMigrator's double for Line 16 in 04da1b6
I've added a TODO about providing another option to control filenames too 👍 .
Started #1166 to track the progress on the improvements to AutoMigrator. If you feel like any of the other changes you've made will make a useful addition, please share your ideas there! Once again, @bgrant0607, appreciate the feedback you've provided so far, it's been very useful. |
|
Thanks! I will take a look. I think my directory problem was a consequence of the way I partially forked just the migrate code and getDirectory() not being exported. WithExcludeTablesLike would work for me, I think. |
This PR is my second attempt at implementing #456 :)
This time around I decided not to meddle with
ALTER TABLEquery and focus on the functionality we want to bring -- AutoMigrator. I took into account our discussions in #726 and left it up to the dialects to implement "alter table" operations, keeping it internal. My thinking was that, if auto migration is done well, the users wouldn't need to work with ALTER TABLE all that much.AutoMigrator exposes a simple and minimal API:
CreateSQLMigrations(ctx)andMigrate(ctx, options). These are similar to Migrator except that they do not require writing any SQL/Go migrations manually.What AutoMigrator can do:
DEFAULTvalueNOT NULLandUNIQUEconstraints.tx.up.sql/.tx.down.sql)What it doesn't do:
AutoMigrator performs schema migrations and not data migrations. For example, when changing a primary key on the table, related foreign keys will not be updated -- they will continue referencing the old PK; to "re-link" them would require updating the referencing values themselves, which is beyond AutoMigrator's scope.
Presently, only
pgdialectsupports database inspection and migration, for which it implements two additional interfaces. AutoMigrator will return an informative error if used with a dialect that doesn't support this feature.Other changes:
test.shforwards additional arguments togo test(for example, now possible to run 1 test with
./test.sh -run=TestAutoMigrator_Run)Schema stringfield to differentiate tables in different schemas.