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
feat(postgres): add name option for enum type #11514
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #11514 +/- ##
==========================================
- Coverage 96.44% 96.33% -0.12%
==========================================
Files 95 95
Lines 9154 9274 +120
Branches 0 90 +90
==========================================
+ Hits 8829 8934 +105
+ Misses 325 323 -2
- Partials 0 17 +17 ☔ View full report in Codecov by Sentry. |
const NamedEnumUser = current.define('user', { | ||
mood: { | ||
type: DataTypes.ENUM({ | ||
name: 'mood', | ||
values: ['happy', 'sad'] | ||
}) | ||
} | ||
}); |
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.
Should there be a test case for an ARRAY
of named ENUM
s?
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.
Happy to add a test, but I don't quite follow. Can you provide an example of exactly what you mean?
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.
Sorry for the late reply. Something like:
const NamedEnumUser = current.define('user', {
mood: {
type: DataTypes.ARRAY(DataTypes.ENUM({
name: 'mood',
values: ['happy', 'sad']
}))
}
});
To ensure an ARRAY
s of named enums works.
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.
Thank you, I will test for this.
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.
I wrote the test for this and realized how this still does not seem right. I'm not sure of a case where you'd want an array of enums for the type. Apologies, maybe this is over my head but as far as I know, when you have a column in PG that is of type enum...there is only one enum type that it is tied to. Can you help me understand a bit more?
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.
I think they're talking about a scenario like this:
CREATE TABLE person (
name text,
current_moods mood[]
);
...where the mood[]
type allows the person to have multiple moods simultaneously.
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.
Ahh, right. That makes sense. Thank you.
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.
Thank you for working on this PR! 👏
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.
As @nmchaves said.
An enumerated type in PostgreSQL is typically a text
type. So think of it as me suggesting an array
of text
which is perfectly valid. The only difference by using an enum instead of text
is obviously that the array values can only be one of the defined constants.
lib/dialects/postgres/data-types.js
Outdated
Utils.generateEnumName(options.field.Model.getTableName(), options.field.fieldName), | ||
'"' | ||
) }[]`; | ||
const enumType = this.type.type || this.type; |
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.
- In
.../postgres/data-types.js
I wasn't a huge fan of thetype.type || type
stuff on line 480, but I just don't understand the code base enough to make an informed refactoring here. Maybe it's fine, but just something I noticed as I was making changes.
Weird indeed, but are you sure this is necessary? What happens when using the code below instead?
const enumType = this.type.type || this.type; | |
const enumType = this.type; |
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.
Made the change, re-ran tests and still passed, so should be good!
Here are the other places where I've added this same check. Tests failed when I removed either of these, so assume they are ok.
File: /lib/dialects/postgres/query-generator.js
Line 466: const enumType = attribute.type.type || attribute.type;
Line 764: const type = dataType.type || dataType;
Not sure if there is any refactoring that should be done here, but just wanted to make note that the reason I originally added these checks were because I saw the code below:
File: /lib/dialects/postgres/query-interface.js
Line 84: const enumType = type.type || type;
Hello! I see you are a first-time contributor, thank you for taking the time to help Sequelize! I hope to see more PRs from you in the future! I have made a first review to your PR above. Thanks for your work :)
This part I haven't looked yet, will do later.
Looks like this only happened locally for you, since all checks have passed in the PR, so don't worry about it. It must be something about your local postgres setup. |
@papb - Thank you! I've used sequelize on many projects and it is a pleasure to help out. 😃 I've pushed my latest updates based on your feedback.
|
Sorry I don't have time to look into it right now... Will do later, hopefully, or maybe another maintainer will show up :) |
@papb - All good! I just wanted to make sure you knew that it was ready for re-review. Thank you! |
Please remove unrelated name changes etc from this branch |
@sushantdhiman -Are you referring to where I've renamed a parameter because I added another? |
Hello @sturdynut, thanks for the patience so far. I am not sure what @sushantdhiman was referring to... Perhaps the change from |
@papb - No problem. I'm happy to make whatever naming changes necessary. Once @sushantdhiman confirms direction I will proceed. |
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.
How does this PR relate to sync({ alter: true })
(#7649)?
I think it would be great if this PR could handle both issues at the same time (and if luckily it already fixes alter: true
as is, please add a test for that).
@papb - This certainly is in the same code. I can add the check for existing enum mentioned in #7649 Still waiting on confirmation as to how to proceed on this PR. I can revert any name changes I made, but I just want to confirm before I slate more time to work on this. Is it just the name change from |
Thanks @sturdynut, let's wait for @sushantdhiman then :) |
Any news on this? Much appreciated feature |
@ShahoG - I was waiting to hear back from @sushantdhiman before moving forward. If I don't hear anything by this weekend, i'm going to make the changes I believe were requested along with the fix from #7649 I don't like having this sitting too long. Cringing thinking about potential merge conflicts, but will make traction on this over the weekend regardless. |
This feature would be easier than having to use litteral queries in migrations or extend DataTypes. How would you use it beyond adding the name? Does it create the enum if it doesn't exist, or should the enum already exists in postgres? |
This feature simply allows you to provide a name for an ENUM type vs having sequelize create it for you using the table name and field name. For existing enums, it already is named, so it wouldn't really help with changing the name, you'd likely need to drop your enum and re-create it. Example:
|
I'm sorry to bother everyone, I would love to see this merged, is there anything specific that is holding this PR back? |
@sturdynut I'm looking forward to this PR! How would I reuse the enum, something like this?
How would I share this enum across multiple model files and migrations? |
This is something I've wanted for a while so I'll likely review it as some point. Can't promise when, work is keeping me busy again :/ |
@ephys - It's been awhile since I looked at this myself, but will keep an eye out for any feedback you provide. 🙌🏼 |
Just noticed this PR is targeting I can handle it if you don't have time but it will be after the PRs I'm currently working on |
Just updated to |
We are refactoring DataTypes in #14505 and, to reduce special-casing, the ENUM DataType is now responsible for generating its SQL name. |
I know you have a lot on your plate right now. What would we need to have that merged in v5 and v6? This is a 3-year-old pull request and although refactoring DataTypes would help, shouldn't we resolve this first? |
Sequelize 5 has been EOL for almost a year now. I personally focus more on fixing the foundations, but I'll review an updated PR that does this in v6 (but not v7 until #14505 has been reviewed and merged) |
Pull Request check-list
Please make sure to review and check all of these items:
npm run test
ornpm run test-DIALECT
pass with this change (including linting)?Description of change
Closes #2577
These changes allow for an optional name when defining enums.
Notes
test/integration/model/count.test.js
file. This was outside of the scope of the feature in I was working on, it was the only linter error and thought the change was pretty minimal enough to slide in..../postgres/query-interface.test.js
, I ended up using thedone()
callback (which I know is called out as something not to do.) , in order to get an accurate failure message. Otherwise the test just times out and you don't see the error from the failedexpect(...)...
;.../postgres/data-types.js
I wasn't a huge fan of thetype.type || type
stuff on line 480, but I just don't understand the code base enough to make an informed refactoring here. Maybe it's fine, but just something I noticed as I was making changes..../postgres/query-generator.js
I updated the signature for thepgEnumDrop(...)
method and reluctantly settled on renaming theenumName
parameter todataTypeOrEnumName
. I did this in order to not break existing calls that provided the name where the dataType was not available. Otherwise I'd have just renamed it todataType
and passed that in for all cases.These are the existing broken integration tests: