3131from pyiceberg .cli .output import ConsoleOutput , JsonOutput , Output
3232from pyiceberg .exceptions import NoSuchNamespaceError , NoSuchPropertyException , NoSuchTableError
3333from pyiceberg .table import TableProperties
34- from pyiceberg .table .refs import SnapshotRef , SnapshotRefType
34+ from pyiceberg .table .refs import MAIN_BRANCH , SnapshotRef , SnapshotRefType
3535from pyiceberg .utils .properties import property_as_int
3636
3737
@@ -179,6 +179,59 @@ def files(ctx: Context, identifier: str, history: bool) -> None:
179179 output .files (catalog_table , history )
180180
181181
182+ @run .command ("delete-files" )
183+ @click .argument ("identifier" )
184+ @click .argument ("file_paths" , nargs = - 1 )
185+ @click .option ("--branch" , default = None , help = "Branch to delete files from (default: main)." )
186+ @click .option (
187+ "--property" ,
188+ "-p" ,
189+ "properties" ,
190+ multiple = True ,
191+ help = "Snapshot property key=value (repeatable)." ,
192+ )
193+ @click .pass_context
194+ @catch_exception ()
195+ def delete_files (
196+ ctx : Context ,
197+ identifier : str ,
198+ file_paths : tuple [str , ...],
199+ branch : str | None ,
200+ properties : tuple [str , ...],
201+ ) -> None :
202+
203+
204+ """
205+ Remove one or more data files from the table by path
206+ """
207+
208+ """Remove one or more data files from the table by path."""
209+ if not file_paths :
210+ raise click .UsageError ("At least one file path is required." )
211+
212+ catalog , output = _catalog_and_output (ctx )
213+
214+ snapshot_properties : dict [str , str ] = {}
215+ for prop in properties :
216+ if "=" not in prop :
217+ raise click .UsageError (f"Property must be in key=value form, got: { prop !r} " )
218+ key , _ , value = prop .partition ("=" )
219+ snapshot_properties [key ] = value
220+
221+ table = catalog .load_table (identifier )
222+
223+ file_paths_list = []
224+ for item in file_paths :
225+ file_paths_list .append (item )
226+
227+ table .delete_files (
228+ file_paths = list (file_paths ),
229+ branch = branch or MAIN_BRANCH ,
230+ snapshot_properties = snapshot_properties
231+ )
232+ output .text (f"Deleted { len (file_paths )} file(s) from { identifier } " )
233+
234+
182235@run .command ()
183236@click .argument ("identifier" )
184237@click .pass_context
@@ -470,3 +523,7 @@ def _retention_properties(ref: SnapshotRef, table_properties: dict[str, str]) ->
470523 retention_properties ["max_ref_age_ms" ] = str (ref .max_ref_age_ms ) if ref .max_ref_age_ms else "forever"
471524
472525 return retention_properties
526+
527+
528+ if __name__ == "__main__" :
529+ run ()
0 commit comments