@@ -60,7 +60,8 @@ def _to_text(
6060 file_path = path
6161 else :
6262 raise RuntimeError ("path and path_root received at the same time." )
63-
63+
64+ pandas_write_mode = pandas_kwargs .pop ("mode" , None )
6465 mode , encoding , newline = _get_write_details (path = file_path , pandas_kwargs = pandas_kwargs )
6566 with open_s3_object (
6667 path = file_path ,
@@ -71,9 +72,22 @@ def _to_text(
7172 encoding = encoding ,
7273 newline = newline ,
7374 ) as f :
75+ if pandas_write_mode == "a" :
76+ # S3 has no native append — read existing content and write it first.
77+ try :
78+ with open_s3_object (
79+ path = file_path ,
80+ mode = "r" if pandas_kwargs .get ("compression" ) is None else "rb" ,
81+ s3_client = s3_client ,
82+ s3_additional_kwargs = s3_additional_kwargs ,
83+ encoding = encoding ,
84+ ) as existing :
85+ f .write (existing .read ())
86+ except Exception :
87+ pass # File does not exist yet — first write, nothing to prepend.
7488 _logger .debug ("pandas_kwargs: %s" , pandas_kwargs )
7589 if file_format == "csv" :
76- df .to_csv (f , mode = mode , ** pandas_kwargs )
90+ df .to_csv (f , ** pandas_kwargs )
7791 elif file_format == "json" :
7892 df .to_json (f , ** pandas_kwargs )
7993 return [file_path ]
@@ -99,6 +113,7 @@ def to_csv( # noqa: PLR0912,PLR0915
99113 bucketing_info : BucketingInfoTuple | None = None ,
100114 concurrent_partitioning : bool = False ,
101115 mode : Literal ["append" , "overwrite" , "overwrite_partitions" ] | None = None ,
116+ pandas_mode : str | None = None ,
102117 catalog_versioning : bool = False ,
103118 schema_evolution : bool = False ,
104119 dtype : dict [str , str ] | None = None ,
@@ -251,6 +266,10 @@ def to_csv( # noqa: PLR0912,PLR0915
251266 valid Pandas arguments in the function call and awswrangler will accept it.
252267 e.g. wr.s3.to_csv(df, path, sep='|', na_rep='NULL', decimal=',')
253268 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html
269+ pandas_mode
270+ Pandas file open mode passed to ``df.to_csv()`` (e.g. ``"a"`` to append).
271+ Distinct from the ``mode`` parameter which controls dataset write behaviour.
272+ Only relevant when ``dataset=False``. Defaults to ``None`` (pandas default ``"w"``).
254273
255274 Returns
256275 -------
@@ -516,6 +535,8 @@ def to_csv( # noqa: PLR0912,PLR0915
516535 pandas_kwargs ["sep" ] = sep
517536 pandas_kwargs ["index" ] = index
518537 pandas_kwargs ["columns" ] = columns
538+ if pandas_mode is not None :
539+ pandas_kwargs ["mode" ] = pandas_mode
519540 _to_text (
520541 df ,
521542 file_format = "csv" ,
0 commit comments