1010from alembic import op
1111import sqlalchemy as sa
1212
13-
14- # revision identifiers, used by Alembic.
1513revision : str = '1b25d7fd62d3'
1614down_revision : Union [str , None ] = 'e85082c4be59'
1715branch_labels : Union [str , Sequence [str ], None ] = None
1816depends_on : Union [str , Sequence [str ], None ] = None
1917
2018
19+ def _movies_table (year_nullable : bool ) -> sa .Table :
20+ return sa .Table (
21+ 'movies' , sa .MetaData (),
22+ sa .Column ('id' , sa .Integer (), autoincrement = True , nullable = False ),
23+ sa .Column ('title' , sa .String (length = 512 ), nullable = False ),
24+ sa .Column ('tmdb_id' , sa .Integer (), nullable = False ),
25+ sa .Column ('year' , sa .SmallInteger (), nullable = year_nullable ),
26+ sa .Column ('size' , sa .Integer (), nullable = True ),
27+ sa .Column ('radarr_id' , sa .Integer (), nullable = True ),
28+ sa .Column ('imdb_id' , sa .String (length = 20 ), nullable = True ),
29+ sa .Column ('tmdb_title' , sa .String (length = 512 ), nullable = True ),
30+ sa .Column ('original_title' , sa .String (length = 512 ), nullable = True ),
31+ sa .Column ('tmdb_release_date' , sa .DateTime (), nullable = True ),
32+ sa .Column ('original_language' , sa .String (length = 10 ), nullable = True ),
33+ sa .Column ('homepage' , sa .String (length = 500 ), nullable = True ),
34+ sa .Column ('origin_country' , sa .JSON (), nullable = True ),
35+ sa .Column ('poster_url' , sa .String (length = 500 ), nullable = True ),
36+ sa .Column ('backdrop_url' , sa .String (length = 500 ), nullable = True ),
37+ sa .Column ('overview' , sa .Text (), nullable = True ),
38+ sa .Column ('genres' , sa .JSON (), nullable = True ),
39+ sa .Column ('popularity' , sa .Float (), nullable = True ),
40+ sa .Column ('vote_average' , sa .Float (), nullable = True ),
41+ sa .Column ('vote_count' , sa .Integer (), nullable = True ),
42+ sa .Column ('revenue' , sa .Integer (), nullable = True ),
43+ sa .Column ('runtime' , sa .Integer (), nullable = True ),
44+ sa .Column ('status' , sa .String (length = 50 ), nullable = True ),
45+ sa .Column ('tagline' , sa .String (length = 255 ), nullable = True ),
46+ sa .Column ('last_viewed_at' , sa .DateTime (), nullable = True ),
47+ sa .Column ('view_count' , sa .Integer (), nullable = False ),
48+ sa .Column ('never_watched' , sa .Boolean (), nullable = False , server_default = '1' ),
49+ sa .Column ('added_at' , sa .DateTime (), nullable = True ),
50+ sa .Column ('removed_at' , sa .DateTime (), nullable = True ),
51+ sa .Column ('last_metadata_refresh_at' , sa .DateTime (), nullable = True ),
52+ sa .PrimaryKeyConstraint ('id' ),
53+ sa .UniqueConstraint ('tmdb_id' ),
54+ sa .UniqueConstraint ('radarr_id' ),
55+ sa .UniqueConstraint ('imdb_id' ),
56+ sa .Index ('ix_movies_tmdb_id' , 'tmdb_id' ),
57+ sa .Index ('ix_movies_radarr_id' , 'radarr_id' ),
58+ sa .Index ('ix_movies_imdb_id' , 'imdb_id' ),
59+ )
60+
61+
62+ def _series_table (year_nullable : bool ) -> sa .Table :
63+ return sa .Table (
64+ 'series' , sa .MetaData (),
65+ sa .Column ('id' , sa .Integer (), autoincrement = True , nullable = False ),
66+ sa .Column ('title' , sa .String (length = 512 ), nullable = False ),
67+ sa .Column ('tmdb_id' , sa .Integer (), nullable = False ),
68+ sa .Column ('year' , sa .SmallInteger (), nullable = year_nullable ),
69+ sa .Column ('size' , sa .Integer (), nullable = True ),
70+ sa .Column ('sonarr_id' , sa .Integer (), nullable = True ),
71+ sa .Column ('imdb_id' , sa .String (length = 20 ), nullable = True ),
72+ sa .Column ('tvdb_id' , sa .String (length = 20 ), nullable = True ),
73+ sa .Column ('tmdb_title' , sa .String (length = 512 ), nullable = True ),
74+ sa .Column ('original_title' , sa .String (length = 512 ), nullable = True ),
75+ sa .Column ('tmdb_first_air_date' , sa .DateTime (), nullable = True ),
76+ sa .Column ('tmdb_last_air_date' , sa .DateTime (), nullable = True ),
77+ sa .Column ('original_language' , sa .String (length = 10 ), nullable = True ),
78+ sa .Column ('homepage' , sa .String (length = 500 ), nullable = True ),
79+ sa .Column ('origin_country' , sa .JSON (), nullable = True ),
80+ sa .Column ('poster_url' , sa .String (length = 500 ), nullable = True ),
81+ sa .Column ('backdrop_url' , sa .String (length = 500 ), nullable = True ),
82+ sa .Column ('overview' , sa .Text (), nullable = True ),
83+ sa .Column ('genres' , sa .JSON (), nullable = True ),
84+ sa .Column ('popularity' , sa .Float (), nullable = True ),
85+ sa .Column ('vote_average' , sa .Float (), nullable = True ),
86+ sa .Column ('vote_count' , sa .Integer (), nullable = True ),
87+ sa .Column ('status' , sa .String (length = 50 ), nullable = True ),
88+ sa .Column ('tagline' , sa .String (length = 255 ), nullable = True ),
89+ sa .Column ('season_count' , sa .Integer (), nullable = True ),
90+ sa .Column ('last_viewed_at' , sa .DateTime (), nullable = True ),
91+ sa .Column ('view_count' , sa .Integer (), nullable = False ),
92+ sa .Column ('never_watched' , sa .Boolean (), nullable = False , server_default = '1' ),
93+ sa .Column ('added_at' , sa .DateTime (), nullable = True ),
94+ sa .Column ('removed_at' , sa .DateTime (), nullable = True ),
95+ sa .Column ('last_metadata_refresh_at' , sa .DateTime (), nullable = True ),
96+ sa .PrimaryKeyConstraint ('id' ),
97+ sa .UniqueConstraint ('tmdb_id' ),
98+ sa .UniqueConstraint ('sonarr_id' ),
99+ sa .UniqueConstraint ('imdb_id' ),
100+ sa .UniqueConstraint ('tvdb_id' ),
101+ sa .Index ('ix_series_tmdb_id' , 'tmdb_id' ),
102+ sa .Index ('ix_series_sonarr_id' , 'sonarr_id' ),
103+ sa .Index ('ix_series_imdb_id' , 'imdb_id' ),
104+ sa .Index ('ix_series_tvdb_id' , 'tvdb_id' ),
105+ )
106+
107+
21108def upgrade () -> None :
22109 conn = op .get_bind ()
23- # drop any orphaned Alembic temp tables left by a previously interrupted migration.
24110 for tbl in ('_alembic_tmp_movies' , '_alembic_tmp_series' ):
25111 conn .execute (sa .text (f'DROP TABLE IF EXISTS "{ tbl } "' ))
26112
27- # SQLite batch_alter_table recreates the table (copy → drop original → rename).
28- # The DROP TABLE fails if FK enforcement is on because child tables reference it.
29113 conn .execute (sa .text ('PRAGMA foreign_keys=OFF' ))
30114 try :
31- with op .batch_alter_table ('movies' , schema = None ) as batch_op :
32- batch_op .alter_column ('year' ,
33- existing_type = sa .SMALLINT (),
34- nullable = True )
35-
36- with op .batch_alter_table ('series' , schema = None ) as batch_op :
37- batch_op .alter_column ('year' ,
38- existing_type = sa .SMALLINT (),
39- nullable = True )
115+ with op .batch_alter_table ('movies' , recreate = 'always' ,
116+ copy_from = _movies_table (year_nullable = False )) as batch_op :
117+ batch_op .alter_column ('year' , existing_type = sa .SMALLINT (), nullable = True )
118+
119+ with op .batch_alter_table ('series' , recreate = 'always' ,
120+ copy_from = _series_table (year_nullable = False )) as batch_op :
121+ batch_op .alter_column ('year' , existing_type = sa .SMALLINT (), nullable = True )
40122 finally :
41123 conn .execute (sa .text ('PRAGMA foreign_keys=ON' ))
42124
@@ -45,14 +127,12 @@ def downgrade() -> None:
45127 conn = op .get_bind ()
46128 conn .execute (sa .text ('PRAGMA foreign_keys=OFF' ))
47129 try :
48- with op .batch_alter_table ('series' , schema = None ) as batch_op :
49- batch_op .alter_column ('year' ,
50- existing_type = sa .SMALLINT (),
51- nullable = False )
52-
53- with op .batch_alter_table ('movies' , schema = None ) as batch_op :
54- batch_op .alter_column ('year' ,
55- existing_type = sa .SMALLINT (),
56- nullable = False )
130+ with op .batch_alter_table ('series' , recreate = 'always' ,
131+ copy_from = _series_table (year_nullable = True )) as batch_op :
132+ batch_op .alter_column ('year' , existing_type = sa .SMALLINT (), nullable = False )
133+
134+ with op .batch_alter_table ('movies' , recreate = 'always' ,
135+ copy_from = _movies_table (year_nullable = True )) as batch_op :
136+ batch_op .alter_column ('year' , existing_type = sa .SMALLINT (), nullable = False )
57137 finally :
58- conn .execute (sa .text ('PRAGMA foreign_keys=ON' ))
138+ conn .execute (sa .text ('PRAGMA foreign_keys=ON' ))
0 commit comments