如何为使用 `dask.dataframe.to_parquet()` 创建的文件夹设置文件夹权限(mkdir 模式)?

How to set folder permissions (mkdir mode) for folders create with `dask.dataframe.to_parquet()`?

我正在尝试指定文件夹权限,然后使用 dask.dataframe.to_parquet()partition_on 参数,因为此参数为提供的 DataFrame 列中的每个组创建一个文件夹。

我尝试了以下代码,但没有成功。在这里,我将 "main" 文件夹的模式设置为 to_parquet,这样文件夹权限为 drwxrws---(由 ls -la 显示),但创建的 partition_on 文件夹具有文件夹权限 drwxr-sr-x:

from pathlib import Path

@dask.delayed
def mkdir(folder_path):
    if not folder_path.exists():
        folder_path.mkdir()
        folder_path.chmod(mode=0o2770)
    return folder_path

path = Path('/scratch/...folder_path.../dataset/')
path_delayed = mkdir(path)

dask.delayed(ddf_postext.to_parquet)(
        path_delayed, compression='brotli', write_index=True, append=False,
        partition_on=['p_k10dato_YYYY_MM'], storage_options={'mode': 0o2770},
        engine='fastparquet')

注意: 任务是 dask.delayed,因为我需要将镶木地板文件保存在与 Dask scheduler/workers 所在的同一台远程计算机上。

我想设置文件夹权限,因为我的 Dask scheduler/workers 正在使用与我的用户在同一组中的 Unix 用户,从而使我的用户能够,例如如果配置了模式和组权限 (27xx),则删除 Dask worker 创建的文件夹。

详细说明:文件夹的模式和权限设置为“2770”。 SGID“2”确保文件夹中的新文件将使用与文件夹本身相同的组权限创建。 umask“770”确保用户和组成员都对文件夹及其文件具有读取、写入和执行权限,而所有其他用户没有权限。

解决方案

正如@mdurant 指出的那样,首先正常保存文件,然后再更改权限。下面的新代码解决了我的文件夹权限问题:

import os
@dask.delayed
def save_parquet_files(ddf, folder_path, to_parquet_kwargs={}):
    """Save Dask DataFrame to parquests with shared group permisions."""
    save_data = ddf.to_parquet(folder_path, **to_parquet_kwargs)

    # set folder permissions as the partition_on argument creates a folder for
    #    each group in the provided DataFrame column.
    if 'partition_on' in to_parquet_kwargs.keys():
        for root, dirs, _ in os.walk(folder_path):  
            for momo in dirs:
                 os.chmod(os.path.join(root, momo), 0o2770)

save_parquet_files(
    ddf_postext, path_delayed, to_parquet_kwargs={
        'compression': 'brotli',
        'append': False,
        'partition_on': ['p_k10dato_YYYY_MM'],
        'engine': 'fastparquet'}).compute()

正确,

storage_options={'mode': 0o2770}

无效:这是文件系统的全局值,所有文件都以 rbabwb 模式使用默认权限打开。

我建议您正常保存文件,然后在

之后制作一个设置权限的函数
def remote_chmod(path):
    for root, dirs, files in os.walk(path):  
        for momo in dirs:  
             os.chmod(os.path.join(root, momo), 0o2770)
        for momo in files:
             os.chmode(os.path.join(root, momo), 0o2770)

client.submit(remote_chmod)

请注意,文件系统 fsspec.implementations.dask.DaskWorkerFileSystem 包含远程工作的操作,如 dask worker 所见 - 但它没有 chmod/own 实现。事实上,它应该被重写,以便可用的方法集取决于所讨论的远程文件系统的class。