Skip to content

pyathena s3 fsspec replacement file system not writing when used with transactions & a context manager #719

Description

@dogversioning

I have a project using fsspec via an abstraction layer. In one place, we provide an alias for fsspec's open method, as follows, using fsspec's transactions:

   @contextlib.contextmanager
    def open(self, mode: str = "r", **kwargs) -> typing.IO:
        """
        Opens the file.

        Writes are atomic by default (the target path will be unaffected until the open is closed).
        Compression will be automatically inferred based on suffix.
        """
        with contextlib.ExitStack() as stack:
            if "w" in mode:
                # fsspec is atomic per-transaction.
                # If an error occurs inside the transaction, partial writes will be discarded.
                # But we only want a transaction if we're writing - read transactions can error out
                stack.enter_context(self.fs.transaction)

            yield stack.enter_context(self.open_direct(mode, **kwargs))

    def open_direct(self, mode: str = "r", **kwargs) -> typing.IO:
        """
        Opens the file directly, without a context manager.

        You must manually call close() yourself.
        The operation will not be atomic.
        """
        # allow callers to override these defaults if they want
        kwargs.setdefault("compression", "infer")
        kwargs.setdefault("encoding", "utf8")
        #print(inspect.stack())
        return self.fs.open(self._path, mode=mode, **kwargs)

When we write to S3 using the transaction using fsspec directly, this works fine. When pyathena replaces fsspec, it this method creates empty files.

I'm working around this currently in the method described in this issue, manually instantiating a s3fs file system.

I think it would be preferable, from a maintenance standpoint, to not entirely replace fsspec when loading a PandasCursor, which would resolve this issue. Otherwise, to maintain API compatibility, it would be nice to support the usage of transactions in this way.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions