-
Notifications
You must be signed in to change notification settings - Fork 29
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
Introspection method returns primary key indexes, making Alembic migrations inconvenient #231
Comments
So, the proposed idea was that Alembic is trying to drop primary keys of tables (while primary keys should be managed automatically by Spanner and never touched by users). To build a migration, Alembic uses an introspection method to understand what is the table structure and what needs to be done. All of it is happening here: And the dialect introspection method is already ignoring primary key indexes:
Thus, it seems Alembic should not try to delete primary key indexes, as it'll not see them in an existing table. I've tried to reproduce the case by creating two tables, one of which is foreign keyed into another, and introspection works fine. I even tried to delete the tables (when it's done with SQLAlchemy, it first drops the table indexes - otherwise Spanner will not allow to drop the table, breaking half of SQLAlchemy functionality). Here are codes: CREATE TABLE Singers (
SingerId INT64 NOT NULL,
FirstName STRING(1024),
Params ARRAY<JSON>,
) PRIMARY KEY (SingerId) CREATE TABLE Song (
SongId INT64 NOT NULL,
Name STRING(256),
Author INT64 NOT NULL,
CONSTRAINT FK_SongAuthor FOREIGN KEY (Author) REFERENCES Singers (SingerId)
) PRIMARY KEY (SongId) Introspection method used by Alembic: from sqlalchemy import create_engine, inspect, Table, MetaData
engine = create_engine(
"spanner+spanner:///projects/*/instances/*/databases/*"
)
inspector = inspect(engine)
print(inspector.get_indexes("Singers"))
# table = Table("Singers", MetaData(bind=engine), autoload=True)
# table.drop() And here is what was generated and executed by SQLAlchemy on my side: DROP INDEX `IDX_Song_Author_C8CE5D5C92C63485`;ALTER TABLE Song DROP CONSTRAINT `FK_SongAuthor`;
DROP TABLE Song; No primary keys affected. Thus, I suspect the problem is not really related to introspection and primary keys. As Alembic's support for indexes and foreign keys constraints is declared to be only basic, the root of the issue is probably in Alembic itself. It'd be good to see traceback of the original error and the migration script generated by Alembic. |
@louimet Would you be able able to take a look at this issue and let us know the error you are facing? |
I started from scratch to be sure to be able to reproduce the error. Using the following declarative classes, I generated first a migration with only the Test class. Then a second one that added the Test2 class, with the foreign key on the first table.
Running those two migrations works fine. But then, if I leave everything as is, i.e. don't change a single thing in my classes, and try to generate a new revision using --autogenerate, I get the following migration :
Running this gives :
For reference, here's the content of the first two migrations: Initial generation :
Add foreign key table:
|
@louimet, instead of: def upgrade() -> None:
op.create_table(
'test',
sa.Column('id', sa.String(length=3), nullable=False),
sa.PrimaryKeyConstraint('id')
) You can write this: def upgrade() -> None:
op.create_table(
"test",
sa.Column("id", sa.String(length=3), primary_key=True),
) It'll generate the same query with NOT NULL and PRIMARY KEY. |
Hm-m... On my end the second migration fails with the error:
Don't you see the same in the migration logs? For a deeper analysis of the error root see this comment. Thus, I suspect here happens the same: migration is actually applied, but Alembic didn't update Let's see if the solution proposed in this comment works. |
Yes, that's the problem we were discussing in that other thread. I was using the emulator here. But I just tried it online with the fix you suggested, and can reproduce the problem. Also, the alembic_version table does show the correct version number (that of the second migration, the one that adds the second table and the foreign key), so that doesn't seem to be the problem. |
Awesome, thanks @IlyaFaer! |
Hi, I can still reproduce this issue in 1.2.1. Generate a migration using these models.
Run |
@louimet, oh, yes. 1.2.1 was released in Aug, while the fixes were made in Sep. |
Oh... Sorry, I'm confused. I was told that the version containing the fixes had been released. I thought it weird that it was dated back from August. Well, that applies to my comment in 232 as well then. I'll clarify the matter. Thanks! |
When we generate migrations with Alembic, it always tries to drop a bunch of indexes. Running the migration fails because they are used by foreign keys.
The dropped indexes are those for the primary key of each table. Those indexes are never explicitly created by Alembic, but they are implicitly by virtue of being on primary key columns. This might explain why Alembic tries to drop them.
Right now, we delete those drop_index manually every time we generate a migration, which is tedious
The text was updated successfully, but these errors were encountered: