-
-
Notifications
You must be signed in to change notification settings - Fork 254
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
enum already exists #1254
Comments
Hi, Moved to alembic. What version are you using? |
this isn't a bug as we dont support adding elements to PG enums, you would have to do this manually using |
I think they are adding a new column of type enum and alembic is generating the migration to add the enum. |
alembic doesnt generate migrations to add enums. The enum gets created only if you run CREATE TABLE via op.create_table(). I dont even see any code that would do this for add_column(). |
alembic==1.8.1 |
Where i have to add this? |
In the revision file that is generated by Alembic, where you have |
Here's how you can get around it: OR you can manually change the name the enum. Here's how to generate this error, replace those steps |
So autogenerate doesn't generate the creation of enum. You manually add it in, here is my example project_status_enum = sa.Enum(
"active",
"deprecated",
"duplicate",
"spam",
"changed_url",
"no_url",
name="enum_project_status",
schema="chai_processed",
)
def upgrade() -> None:
project_status_enum.create(op.get_bind(), checkfirst=True)
# other stuff I kept running into the DuplicateViolation error.
I switched the logging level to INFO to see the actual SQLs that alembic was running, and saw it was creating the enum type twice:
That first query returned nothing (since no enum existed). The second query created the enum. The third query...why was it doing it again? My guess is the first So, can anyone confirm that creating the Enum field outside of the actual |
Other stuff here is important |
op.create_table(
"agg_projects_processed",
sa.Column(
"tid",
sa.Integer(),
sa.Identity(
always=False,
start=1,
increment=1,
nomaxvalue=True,
cycle=False,
minvalue=1,
),
nullable=False,
),
sa.Column("project_name", sa.String(), nullable=False),
sa.Column(
"status", project_status_enum, nullable=False, server_default="active"
),
sa.PrimaryKeyConstraint("tid", name=op.f("pk_agg_projects_processed")),
schema="chai_processed",
) creating 4 other tables, none of which use project_status_enum |
Also @CaselIT, to your earlier point, did you mean |
you are using the enum right here sa.Column(
"status", project_status_enum, nullable=False, server_default="active"
), that's why it gets created. please see also #1347 if you want to use |
I have similar issue I trying to reuse enum (which created in one of previous migrations), but getting error:
I want to help to fix this issue, it is this same, as described? |
Using the postgresql specific type you can indicate in the migration not to create the type: |
I encountered this error after creating a new model with an enum column. I could create and execute the migration ( def upgrade():
op.create_table(
"my_table",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("source", sa.Enum("SOURCE_ENUM", name="source_enum"), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
def downgrade():
op.drop_table("my_table")
op.execute("DROP TYPE source_enum") # <-- This is what I added manually I'm using SQLAlchemy 1.4. |
I had the same issue for the first migration when the enum is in the table and it is necessary to upgrade. when I had this code: sa.Column('role', postgresql.ENUM('USER', 'STAFF', name='role_enum'), nullable=True), I was getting: sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateObject) type "role_enum" already exists I understood that when creating the table with already available enum it is better to change create_type=False so that it won't double check. sa.Column('role', postgresql.ENUM('USER', 'STAFF', name='role_enum', create_type=False), nullable=True), I hope it will be helpful |
I guess it will work, what if we create new enum fields and choices ?
Thanks and Regards,
Chirayu Shukla
Software Engineer
Python | Thoughtwin IT Solutions
[image: mobilePhone] 9039901501
…On Sun, 31 Mar 2024 at 1:53 PM, Eldiiar ***@***.***> wrote:
I had the same issue for the first migration when the enum is in the table
and it is necessary to upgrade.
when I had this code:
sa.Column('role', postgresql.ENUM('USER', 'STAFF', name='role_enum'), nullable=True),
I was getting:
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateObject) type "role_enum" already exists
But I read this explanation:
Screenshot.from.2024-03-31.14-18-04.png (view on web)
<https://github.com/sqlalchemy/alembic/assets/110094562/897a9787-5704-408c-8d07-f000e8f43fed>
I understood that when creating the table with already available enum it
is better to change create_type=False so that it won't double check.
And I was able to overcome it with this addition:
sa.Column('role', postgresql.ENUM('USER', 'STAFF', name='role_enum', create_type=False), nullable=True),
I hope it will be helpful
—
Reply to this email directly, view it on GitHub
<#1254 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A6GOACNDJHMLX2U2UWCWICLY27BXTAVCNFSM6AAAAAAYSVANLCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRYGU4TQNRUHA>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
I had same issue. I have pgAdmin you should remove "tickettype" from your database-name -> shemas -> public -> Types section of pgAdmin and the run alembic command to migrate. |
I know we can specify
So it seems the detection feature is at fault since it try to create it. I also like alembic generate migration file and doesn't need to touch them (here the workaround require to modify generate file, know that a previous migration did add the type, if enum have correct values, ...) so I tried something like: class WarningEnum(enum.Enum):
critical = "CRITIQUE"
warning = "Avertissement"
info = "Information"
class SomeAddedClass(Base):
__tablename__ = "some_added_class"
level: Mapped[WarningEnum] = mapped_column(type_=postgresql.ENUM(WarningEnum, create_type=False))
id: Mapped[int] = mapped_column(primary_key=True) In the hope that def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('some_added_class',
sa.Column('level', postgresql.ENUM('critical', 'warning', 'info', name='warningenum'), nullable=False),
sa.Column('id', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ### Also the solution of deleting types is not suitable because some data depends on it. |
alembic doesnt detect changes in ENUM right now or really do anything with them at all. the kinds of changes that would be emitted when the contents change are very complicated to guess automatically due to the many individual operations supported or not by PostgreSQL, so instead of making hasty decisions and getting it wrong, we've intentionally stayed away from alteration of enums. for this reason we've held off on getting into ENUM however there is an alembic extension that has taken on this task which you can see in https://pypi.org/project/alembic-postgresql-enum/ . I would take a look at this project and see if these extensions suit your needs. |
Thanks, I just tested this plugin today and it make alembic works as excepted. I can add column that mention a previously created enum without having to manipulate db nor migration file (I think like OP did). downgrade/upgrade now apply cleany (even with data that use the enum: drop enum cascade). I guess now I am locked with postgresql for my schema (it is acceptable), and I should be aware that renaming enum should be done with caution (I think I will just add new variant without removing old one). Detecting enum renaming is a problem that protobuf suggests just to add enum and reserve old one (so we can see which one is considered deleted and which one are really new). This plugin offer a way to specify a renaming so I can use it as last resort (if I really wanted to rename: I can just change the value in python code instead of renaming the field). Just to come back to the issue: in postgresql we can introspect enum but not in other dialect so the default alembic behavior is a bit silly to always emit a create statement ? |
you can introspect ENUM types in MySQL/MariaDB as well. for all other backends ENUM just uses VARCHAR. |
Describe the bug
Whenever I am adding Enum field in a new model it's giving me this error "sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateObject) type "tickettype" already exists" for resolving this I have to delete DB and create a new one.
Optional link from https://docs.sqlalchemy.org which documents the behavior that is expected
https://docs.sqlalchemy.org/en/14/errors.html#error-f405
SQLAlchemy Version in Use
1.4.46
DBAPI (i.e. the database driver)
2.9.5
Database Vendor and Major Version
2.9.5
Python Version
3.8
Operating system
Linux
To Reproduce
Error
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateObject) type "tickettype" already exists
[SQL: CREATE TYPE tickettype AS ENUM ('PAID', 'FREE', 'GROUP', 'DONATION', 'REQUEST', 'GUESTLIST')]
Additional context
No response
The text was updated successfully, but these errors were encountered: