Skip to content

Commit 3cbe8ad

Browse files
committed
fix more migration issues
1 parent 6f66e8d commit 3cbe8ad

File tree

2 files changed

+149
-88
lines changed

2 files changed

+149
-88
lines changed

compose/backend/migrations/versions/99078464479b_.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,23 @@ def upgrade():
108108
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
109109
sa.Column('name', sa.Text(), nullable=True),
110110
sa.Column('description', sa.Text(), nullable=True),
111-
sa.Column('specification_id', sa.Text(), nullable=False),
112-
sa.Column('studyset_id', sa.Text(), nullable=False),
113-
sa.Column('annotation_id', sa.Text(), nullable=False),
111+
sa.Column('specification_id', sa.Text(), nullable=True),
112+
sa.Column('studyset_id', sa.Text(), nullable=True),
113+
sa.Column('annotation_id', sa.Text(), nullable=True),
114114
sa.Column('user_id', sa.Text(), nullable=True),
115115
sa.ForeignKeyConstraint(['annotation_id'], ['annotations.id'], ),
116116
sa.ForeignKeyConstraint(['specification_id'], ['specifications.id'], ),
117117
sa.ForeignKeyConstraint(['studyset_id'], ['studysets.id'], ),
118118
sa.ForeignKeyConstraint(['user_id'], ['users.external_id'], ),
119-
sa.PrimaryKeyConstraint('id', 'specification_id', 'studyset_id', 'annotation_id')
119+
sa.PrimaryKeyConstraint('id')
120120
)
121+
else:
122+
existing_uniques = {
123+
tuple(constraint.get("column_names", []))
124+
for constraint in inspector.get_unique_constraints('meta_analyses')
125+
}
126+
if ('id',) not in existing_uniques:
127+
op.create_unique_constraint('uq_meta_analyses_id', 'meta_analyses', ['id'])
121128
# ### end Alembic commands ###
122129

123130

compose/backend/migrations/versions/e1c296d89bf1_.py

Lines changed: 138 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -19,90 +19,144 @@
1919

2020
def upgrade():
2121
# ### commands auto generated by Alembic - please adjust! ###
22-
op.create_table('devices',
23-
sa.Column('id', sa.Text(), nullable=False),
24-
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
25-
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
26-
sa.Column('device_name', sa.String(), nullable=True),
27-
sa.Column('api_key', sa.String(), nullable=True),
28-
sa.Column('user_id', sa.Text(), nullable=True),
29-
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
30-
sa.PrimaryKeyConstraint('id')
31-
)
32-
op.create_table('neurostore_studies',
33-
sa.Column('id', sa.Text(), nullable=False),
34-
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
35-
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
36-
sa.Column('neurostore_id', sa.Text(), nullable=True),
37-
sa.Column('exception', sa.Text(), nullable=True),
38-
sa.Column('traceback', sa.Text(), nullable=True),
39-
sa.Column('status', sa.Text(), nullable=True),
40-
sa.Column('project_id', sa.Text(), nullable=True),
41-
sa.CheckConstraint("status IN ('OK', 'FAILED', 'PENDING')"),
42-
sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ),
43-
sa.PrimaryKeyConstraint('id'),
44-
sa.UniqueConstraint('neurostore_id')
45-
)
46-
op.create_table('neurostore_analyses',
47-
sa.Column('id', sa.Text(), nullable=False),
48-
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
49-
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
50-
sa.Column('neurostore_id', sa.Text(), nullable=True),
51-
sa.Column('exception', sa.Text(), nullable=True),
52-
sa.Column('traceback', sa.Text(), nullable=True),
53-
sa.Column('status', sa.Text(), nullable=True),
54-
sa.Column('meta_analysis_id', sa.Text(), nullable=True),
55-
sa.Column('neurostore_study_id', sa.Text(), nullable=True),
56-
sa.CheckConstraint("status IN ('OK', 'FAILED', 'PENDING')"),
57-
sa.ForeignKeyConstraint(['meta_analysis_id'], ['meta_analyses.id'], ),
58-
sa.ForeignKeyConstraint(['neurostore_study_id'], ['neurostore_studies.neurostore_id'], ),
59-
sa.PrimaryKeyConstraint('id'),
60-
sa.UniqueConstraint('meta_analysis_id'),
61-
sa.UniqueConstraint('neurostore_id')
62-
)
63-
op.create_table('neurovault_files',
64-
sa.Column('id', sa.Text(), nullable=False),
65-
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
66-
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
67-
sa.Column('collection_id', sa.Integer(), nullable=False),
68-
sa.Column('image_id', sa.Integer(), nullable=True),
69-
sa.Column('filename', sa.Text(), nullable=True),
70-
sa.Column('url', sa.Text(), nullable=True),
71-
sa.Column('space', sa.Text(), nullable=True),
72-
sa.Column('value_type', sa.Text(), nullable=True),
73-
sa.Column('exception', sa.Text(), nullable=True),
74-
sa.Column('traceback', sa.Text(), nullable=True),
75-
sa.Column('status', sa.Text(), nullable=True),
76-
sa.CheckConstraint("status IN ('OK', 'FAILED', 'PENDING')"),
77-
sa.ForeignKeyConstraint(['collection_id'], ['neurovault_collections.collection_id'], ),
78-
sa.PrimaryKeyConstraint('id'),
79-
sa.UniqueConstraint('image_id')
80-
)
81-
op.drop_table('neurovault_file')
82-
op.add_column('annotations', sa.Column('cached_studyset_id', sa.Text(), nullable=True))
83-
op.drop_constraint('annotations_internal_studyset_id_fkey', 'annotations', type_='foreignkey')
84-
op.create_foreign_key(None, 'annotations', 'studysets', ['cached_studyset_id'], ['id'])
85-
op.drop_column('annotations', 'internal_studyset_id')
86-
op.drop_column('annotations', 'public')
87-
op.add_column('meta_analyses', sa.Column('neurostore_studyset_id', sa.Text(), nullable=True))
88-
op.add_column('meta_analyses', sa.Column('neurostore_annotation_id', sa.Text(), nullable=True))
89-
op.add_column('meta_analyses', sa.Column('cached_studyset_id', sa.Text(), nullable=True))
90-
op.add_column('meta_analyses', sa.Column('cached_annotation_id', sa.Text(), nullable=True))
91-
op.add_column('meta_analyses', sa.Column('run_key', sa.Text(), nullable=True))
92-
op.drop_constraint('meta_analyses_internal_studyset_id_fkey', 'meta_analyses', type_='foreignkey')
93-
op.drop_constraint('meta_analyses_internal_annotation_id_fkey', 'meta_analyses', type_='foreignkey')
94-
op.create_foreign_key(None, 'meta_analyses', 'annotations', ['cached_annotation_id'], ['id'])
95-
op.create_foreign_key(None, 'meta_analyses', 'annotation_references', ['neurostore_annotation_id'], ['id'])
96-
op.create_foreign_key(None, 'meta_analyses', 'studysets', ['cached_studyset_id'], ['id'])
97-
op.create_foreign_key(None, 'meta_analyses', 'studyset_references', ['neurostore_studyset_id'], ['id'])
98-
op.drop_column('meta_analyses', 'internal_annotation_id')
99-
op.drop_column('meta_analyses', 'internal_studyset_id')
100-
op.add_column('meta_analysis_results', sa.Column('method_description', sa.Text(), nullable=True))
101-
op.drop_constraint('meta_analysis_results_neurostore_id_key', 'meta_analysis_results', type_='unique')
102-
op.drop_column('meta_analysis_results', 'neurostore_id')
103-
op.add_column('projects', sa.Column('public', sa.Boolean(), nullable=True))
104-
op.drop_column('specifications', 'public')
105-
op.drop_column('studysets', 'public')
22+
bind = op.get_bind()
23+
inspector = sa.inspect(bind)
24+
25+
if not inspector.has_table('devices'):
26+
op.create_table('devices',
27+
sa.Column('id', sa.Text(), nullable=False),
28+
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
29+
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
30+
sa.Column('device_name', sa.String(), nullable=True),
31+
sa.Column('api_key', sa.String(), nullable=True),
32+
sa.Column('user_id', sa.Text(), nullable=True),
33+
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
34+
sa.PrimaryKeyConstraint('id')
35+
)
36+
37+
if not inspector.has_table('neurostore_studies'):
38+
op.create_table('neurostore_studies',
39+
sa.Column('id', sa.Text(), nullable=False),
40+
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
41+
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
42+
sa.Column('neurostore_id', sa.Text(), nullable=True),
43+
sa.Column('exception', sa.Text(), nullable=True),
44+
sa.Column('traceback', sa.Text(), nullable=True),
45+
sa.Column('status', sa.Text(), nullable=True),
46+
sa.Column('project_id', sa.Text(), nullable=True),
47+
sa.CheckConstraint("status IN ('OK', 'FAILED', 'PENDING')"),
48+
sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ),
49+
sa.PrimaryKeyConstraint('id'),
50+
sa.UniqueConstraint('neurostore_id')
51+
)
52+
53+
if not inspector.has_table('neurostore_analyses'):
54+
op.create_table('neurostore_analyses',
55+
sa.Column('id', sa.Text(), nullable=False),
56+
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
57+
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
58+
sa.Column('neurostore_id', sa.Text(), nullable=True),
59+
sa.Column('exception', sa.Text(), nullable=True),
60+
sa.Column('traceback', sa.Text(), nullable=True),
61+
sa.Column('status', sa.Text(), nullable=True),
62+
sa.Column('meta_analysis_id', sa.Text(), nullable=True),
63+
sa.Column('neurostore_study_id', sa.Text(), nullable=True),
64+
sa.CheckConstraint("status IN ('OK', 'FAILED', 'PENDING')"),
65+
sa.ForeignKeyConstraint(['meta_analysis_id'], ['meta_analyses.id'], ),
66+
sa.ForeignKeyConstraint(['neurostore_study_id'], ['neurostore_studies.neurostore_id'], ),
67+
sa.PrimaryKeyConstraint('id'),
68+
sa.UniqueConstraint('meta_analysis_id'),
69+
sa.UniqueConstraint('neurostore_id')
70+
)
71+
72+
if not inspector.has_table('neurovault_files'):
73+
op.create_table('neurovault_files',
74+
sa.Column('id', sa.Text(), nullable=False),
75+
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
76+
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
77+
sa.Column('collection_id', sa.Integer(), nullable=False),
78+
sa.Column('image_id', sa.Integer(), nullable=True),
79+
sa.Column('filename', sa.Text(), nullable=True),
80+
sa.Column('url', sa.Text(), nullable=True),
81+
sa.Column('space', sa.Text(), nullable=True),
82+
sa.Column('value_type', sa.Text(), nullable=True),
83+
sa.Column('exception', sa.Text(), nullable=True),
84+
sa.Column('traceback', sa.Text(), nullable=True),
85+
sa.Column('status', sa.Text(), nullable=True),
86+
sa.CheckConstraint("status IN ('OK', 'FAILED', 'PENDING')"),
87+
sa.ForeignKeyConstraint(['collection_id'], ['neurovault_collections.collection_id'], ),
88+
sa.PrimaryKeyConstraint('id'),
89+
sa.UniqueConstraint('image_id')
90+
)
91+
92+
# If the legacy neurovault_file table exists, drop it (it was renamed to neurovault_files)
93+
if inspector.has_table('neurovault_file'):
94+
op.drop_table('neurovault_file')
95+
96+
annotation_columns = {c['name'] for c in inspector.get_columns('annotations')}
97+
annotation_fk_names = {fk.get('name') for fk in inspector.get_foreign_keys('annotations')}
98+
99+
if 'cached_studyset_id' not in annotation_columns:
100+
op.add_column('annotations', sa.Column('cached_studyset_id', sa.Text(), nullable=True))
101+
op.create_foreign_key(None, 'annotations', 'studysets', ['cached_studyset_id'], ['id'])
102+
103+
if 'annotations_internal_studyset_id_fkey' in annotation_fk_names:
104+
op.drop_constraint('annotations_internal_studyset_id_fkey', 'annotations', type_='foreignkey')
105+
if 'internal_studyset_id' in annotation_columns:
106+
op.drop_column('annotations', 'internal_studyset_id')
107+
if 'public' in annotation_columns:
108+
op.drop_column('annotations', 'public')
109+
110+
meta_columns = {c['name'] for c in inspector.get_columns('meta_analyses')}
111+
meta_fk_names = {fk.get('name') for fk in inspector.get_foreign_keys('meta_analyses')}
112+
113+
for col in ('neurostore_studyset_id', 'neurostore_annotation_id', 'cached_studyset_id', 'cached_annotation_id', 'run_key'):
114+
if col not in meta_columns:
115+
op.add_column('meta_analyses', sa.Column(col, sa.Text(), nullable=True))
116+
117+
if 'meta_analyses_internal_studyset_id_fkey' in meta_fk_names:
118+
op.drop_constraint('meta_analyses_internal_studyset_id_fkey', 'meta_analyses', type_='foreignkey')
119+
if 'meta_analyses_internal_annotation_id_fkey' in meta_fk_names:
120+
op.drop_constraint('meta_analyses_internal_annotation_id_fkey', 'meta_analyses', type_='foreignkey')
121+
122+
# Only create new FKs if they are not already present
123+
existing_meta_fk_targets = {(fk['constrained_columns'][0], fk['referred_table']) for fk in inspector.get_foreign_keys('meta_analyses')}
124+
if ('cached_annotation_id', 'annotations') not in existing_meta_fk_targets:
125+
op.create_foreign_key(None, 'meta_analyses', 'annotations', ['cached_annotation_id'], ['id'])
126+
if ('neurostore_annotation_id', 'annotation_references') not in existing_meta_fk_targets:
127+
op.create_foreign_key(None, 'meta_analyses', 'annotation_references', ['neurostore_annotation_id'], ['id'])
128+
if ('cached_studyset_id', 'studysets') not in existing_meta_fk_targets:
129+
op.create_foreign_key(None, 'meta_analyses', 'studysets', ['cached_studyset_id'], ['id'])
130+
if ('neurostore_studyset_id', 'studyset_references') not in existing_meta_fk_targets:
131+
op.create_foreign_key(None, 'meta_analyses', 'studyset_references', ['neurostore_studyset_id'], ['id'])
132+
133+
if 'internal_annotation_id' in meta_columns:
134+
op.drop_column('meta_analyses', 'internal_annotation_id')
135+
if 'internal_studyset_id' in meta_columns:
136+
op.drop_column('meta_analyses', 'internal_studyset_id')
137+
138+
results_columns = {c['name'] for c in inspector.get_columns('meta_analysis_results')}
139+
unique_constraints = inspector.get_unique_constraints('meta_analysis_results')
140+
unique_names = {uc.get('name') for uc in unique_constraints}
141+
142+
if 'method_description' not in results_columns:
143+
op.add_column('meta_analysis_results', sa.Column('method_description', sa.Text(), nullable=True))
144+
if 'meta_analysis_results_neurostore_id_key' in unique_names:
145+
op.drop_constraint('meta_analysis_results_neurostore_id_key', 'meta_analysis_results', type_='unique')
146+
if 'neurostore_id' in results_columns:
147+
op.drop_column('meta_analysis_results', 'neurostore_id')
148+
149+
project_columns = {c['name'] for c in inspector.get_columns('projects')}
150+
if 'public' not in project_columns:
151+
op.add_column('projects', sa.Column('public', sa.Boolean(), nullable=True))
152+
153+
spec_columns = {c['name'] for c in inspector.get_columns('specifications')}
154+
if 'public' in spec_columns:
155+
op.drop_column('specifications', 'public')
156+
157+
studyset_columns = {c['name'] for c in inspector.get_columns('studysets')}
158+
if 'public' in studyset_columns:
159+
op.drop_column('studysets', 'public')
106160
# ### end Alembic commands ###
107161

108162

0 commit comments

Comments
 (0)