1+ # File: /alembic_db/versions/0001_assets.py
12"""initial assets schema + per-asset state cache
23
34Revision ID: 0001_assets
@@ -22,15 +23,12 @@ def upgrade() -> None:
2223 sa .Column ("size_bytes" , sa .BigInteger (), nullable = False , server_default = "0" ),
2324 sa .Column ("mime_type" , sa .String (length = 255 ), nullable = True ),
2425 sa .Column ("refcount" , sa .BigInteger (), nullable = False , server_default = "0" ),
25- sa .Column ("storage_backend" , sa .String (length = 32 ), nullable = False , server_default = "fs" ),
26- sa .Column ("storage_locator" , sa .Text (), nullable = False ),
2726 sa .Column ("created_at" , sa .DateTime (timezone = False ), nullable = False ),
2827 sa .Column ("updated_at" , sa .DateTime (timezone = False ), nullable = False ),
2928 sa .CheckConstraint ("size_bytes >= 0" , name = "ck_assets_size_nonneg" ),
3029 sa .CheckConstraint ("refcount >= 0" , name = "ck_assets_refcount_nonneg" ),
3130 )
3231 op .create_index ("ix_assets_mime_type" , "assets" , ["mime_type" ])
33- op .create_index ("ix_assets_backend_locator" , "assets" , ["storage_backend" , "storage_locator" ])
3432
3533 # ASSETS_INFO: user-visible references (mutable metadata)
3634 op .create_table (
@@ -52,11 +50,12 @@ def upgrade() -> None:
5250 op .create_index ("ix_assets_info_name" , "assets_info" , ["name" ])
5351 op .create_index ("ix_assets_info_created_at" , "assets_info" , ["created_at" ])
5452 op .create_index ("ix_assets_info_last_access_time" , "assets_info" , ["last_access_time" ])
53+ op .create_index ("ix_assets_info_owner_name" , "assets_info" , ["owner_id" , "name" ])
5554
5655 # TAGS: normalized tag vocabulary
5756 op .create_table (
5857 "tags" ,
59- sa .Column ("name" , sa .String (length = 128 ), primary_key = True ),
58+ sa .Column ("name" , sa .String (length = 512 ), primary_key = True ),
6059 sa .Column ("tag_type" , sa .String (length = 32 ), nullable = False , server_default = "user" ),
6160 sa .CheckConstraint ("name = lower(name)" , name = "ck_tags_lowercase" ),
6261 )
@@ -65,8 +64,8 @@ def upgrade() -> None:
6564 # ASSET_INFO_TAGS: many-to-many for tags on AssetInfo
6665 op .create_table (
6766 "asset_info_tags" ,
68- sa .Column ("asset_info_id" , sa .BigInteger (), sa .ForeignKey ("assets_info.id" , ondelete = "CASCADE" ), nullable = False ),
69- sa .Column ("tag_name" , sa .String (length = 128 ), sa .ForeignKey ("tags.name" , ondelete = "RESTRICT" ), nullable = False ),
67+ sa .Column ("asset_info_id" , sa .Integer (), sa .ForeignKey ("assets_info.id" , ondelete = "CASCADE" ), nullable = False ),
68+ sa .Column ("tag_name" , sa .String (length = 512 ), sa .ForeignKey ("tags.name" , ondelete = "RESTRICT" ), nullable = False ),
7069 sa .Column ("origin" , sa .String (length = 32 ), nullable = False , server_default = "manual" ),
7170 sa .Column ("added_by" , sa .String (length = 128 ), nullable = True ),
7271 sa .Column ("added_at" , sa .DateTime (timezone = False ), nullable = False ),
@@ -75,15 +74,15 @@ def upgrade() -> None:
7574 op .create_index ("ix_asset_info_tags_tag_name" , "asset_info_tags" , ["tag_name" ])
7675 op .create_index ("ix_asset_info_tags_asset_info_id" , "asset_info_tags" , ["asset_info_id" ])
7776
78- # ASSET_LOCATOR_STATE : 1:1 filesystem metadata(for fast integrity checking) for an Asset records
77+ # ASSET_CACHE_STATE : 1:1 local cache metadata for an Asset
7978 op .create_table (
80- "asset_locator_state " ,
79+ "asset_cache_state " ,
8180 sa .Column ("asset_hash" , sa .String (length = 256 ), sa .ForeignKey ("assets.hash" , ondelete = "CASCADE" ), primary_key = True ),
81+ sa .Column ("file_path" , sa .Text (), nullable = False ), # absolute local path to cached file
8282 sa .Column ("mtime_ns" , sa .BigInteger (), nullable = True ),
83- sa .Column ("etag" , sa .String (length = 256 ), nullable = True ),
84- sa .Column ("last_modified" , sa .String (length = 128 ), nullable = True ),
85- sa .CheckConstraint ("(mtime_ns IS NULL) OR (mtime_ns >= 0)" , name = "ck_als_mtime_nonneg" ),
83+ sa .CheckConstraint ("(mtime_ns IS NULL) OR (mtime_ns >= 0)" , name = "ck_acs_mtime_nonneg" ),
8684 )
85+ op .create_index ("ix_asset_cache_state_file_path" , "asset_cache_state" , ["file_path" ])
8786
8887 # ASSET_INFO_META: typed KV projection of user_metadata for filtering/sorting
8988 op .create_table (
@@ -102,6 +101,21 @@ def upgrade() -> None:
102101 op .create_index ("ix_asset_info_meta_key_val_num" , "asset_info_meta" , ["key" , "val_num" ])
103102 op .create_index ("ix_asset_info_meta_key_val_bool" , "asset_info_meta" , ["key" , "val_bool" ])
104103
104+ # ASSET_LOCATIONS: remote locations per asset
105+ op .create_table (
106+ "asset_locations" ,
107+ sa .Column ("id" , sa .Integer (), primary_key = True , autoincrement = True ),
108+ sa .Column ("asset_hash" , sa .String (length = 256 ), sa .ForeignKey ("assets.hash" , ondelete = "CASCADE" ), nullable = False ),
109+ sa .Column ("provider" , sa .String (length = 32 ), nullable = False ), # e.g., "gcs"
110+ sa .Column ("locator" , sa .Text (), nullable = False ), # e.g., "gs://bucket/path/to/blob"
111+ sa .Column ("expected_size_bytes" , sa .BigInteger (), nullable = True ),
112+ sa .Column ("etag" , sa .String (length = 256 ), nullable = True ),
113+ sa .Column ("last_modified" , sa .String (length = 128 ), nullable = True ),
114+ sa .UniqueConstraint ("asset_hash" , "provider" , "locator" , name = "uq_asset_locations_triplet" ),
115+ )
116+ op .create_index ("ix_asset_locations_hash" , "asset_locations" , ["asset_hash" ])
117+ op .create_index ("ix_asset_locations_provider" , "asset_locations" , ["provider" ])
118+
105119 # Tags vocabulary for models
106120 tags_table = sa .table (
107121 "tags" ,
@@ -143,13 +157,18 @@ def upgrade() -> None:
143157
144158
145159def downgrade () -> None :
160+ op .drop_index ("ix_asset_locations_provider" , table_name = "asset_locations" )
161+ op .drop_index ("ix_asset_locations_hash" , table_name = "asset_locations" )
162+ op .drop_table ("asset_locations" )
163+
146164 op .drop_index ("ix_asset_info_meta_key_val_bool" , table_name = "asset_info_meta" )
147165 op .drop_index ("ix_asset_info_meta_key_val_num" , table_name = "asset_info_meta" )
148166 op .drop_index ("ix_asset_info_meta_key_val_str" , table_name = "asset_info_meta" )
149167 op .drop_index ("ix_asset_info_meta_key" , table_name = "asset_info_meta" )
150168 op .drop_table ("asset_info_meta" )
151169
152- op .drop_table ("asset_locator_state" )
170+ op .drop_index ("ix_asset_cache_state_file_path" , table_name = "asset_cache_state" )
171+ op .drop_table ("asset_cache_state" )
153172
154173 op .drop_index ("ix_asset_info_tags_asset_info_id" , table_name = "asset_info_tags" )
155174 op .drop_index ("ix_asset_info_tags_tag_name" , table_name = "asset_info_tags" )
@@ -159,13 +178,13 @@ def downgrade() -> None:
159178 op .drop_table ("tags" )
160179
161180 op .drop_constraint ("uq_assets_info_hash_owner_name" , table_name = "assets_info" )
181+ op .drop_index ("ix_assets_info_owner_name" , table_name = "assets_info" )
162182 op .drop_index ("ix_assets_info_last_access_time" , table_name = "assets_info" )
163183 op .drop_index ("ix_assets_info_created_at" , table_name = "assets_info" )
164184 op .drop_index ("ix_assets_info_name" , table_name = "assets_info" )
165185 op .drop_index ("ix_assets_info_asset_hash" , table_name = "assets_info" )
166186 op .drop_index ("ix_assets_info_owner_id" , table_name = "assets_info" )
167187 op .drop_table ("assets_info" )
168188
169- op .drop_index ("ix_assets_backend_locator" , table_name = "assets" )
170189 op .drop_index ("ix_assets_mime_type" , table_name = "assets" )
171190 op .drop_table ("assets" )
0 commit comments