Code Workspaces의 원본 데이터셋 파일
스키마가 있는 표 데이터를 분석하려면 테이블 읽기 또는 SQL을 사용합니다. 파티션 파일이 많거나 파일 이름이 실행마다 바뀌어도 논리 테이블로 읽을 수 있습니다.
파일 자체가 필요한 경우에는 데이터셋의 현재 뷰에 있는 파일을 내려받습니다. 다운로드 결과는 논리 파일 이름에서 로컬 경로로의 매핑입니다. 논리 이름에는 슬래시가 들어갈 수 있고 로컬 경로는 바뀔 수 있으므로 매핑의 키를 기준으로 접근합니다.
이름을 알고 있는 파일
가상 비정형 데이터셋 Dogs가 puppies 별칭으로 등록되어 있고 puppy_names.txt가 UTF-8 텍스트라고 가정합니다.
Python:
from foundry.transforms import Dataset
puppies_files = Dataset.get("puppies").files().download()
with open(puppies_files["puppy_names.txt"], "rb") as file:
puppy_names_text = file.read().decode("utf-8")
R:
library(foundry)
puppies_files <- datasets.list_files("puppies")
puppies_local_files <- datasets.download_files("puppies", puppies_files)
puppy_names_text <- readLines(
puppies_local_files[["puppy_names.txt"]], warn = FALSE, encoding = "UTF-8"
)
파일 이름이 없는 경우와 내용이 지정 인코딩의 텍스트가 아닌 경우를 구분해야 합니다. 바이너리 파일에는 해당 형식의 읽기 함수를 사용합니다.
파일 이름과 개수가 바뀌는 입력
Python의 download는 파일 이름과 로컬 경로를 반환하므로 이름을 하드코딩하지 않고 모두 처리할 수 있습니다. 다음 예는 실제 파일 내용을 읽어 파일별 SHA-256을 계산합니다.
import hashlib
from foundry.transforms import Dataset
def file_digests(downloaded_files: dict[str, str]) -> dict[str, str]:
digests = {}
for file_name, local_path in downloaded_files.items():
digest = hashlib.sha256()
with open(local_path, "rb") as file:
for block in iter(lambda: file.read(1024 * 1024), b""):
digest.update(block)
digests[file_name] = digest.hexdigest()
return digests
downloaded_files = Dataset.get("puppies").files().download()
digests = file_digests(downloaded_files)
특정 디렉터리 접두사만 처리하려면 다운로드 전에 메타데이터를 필터합니다.
from foundry.transforms import Dataset
downloaded_files = (
Dataset.get("puppies").files()
.filter(lambda file: file.path.startswith("2024/"))
.download()
)
digests_2024 = file_digests(downloaded_files)
Python files의 기본 목록은 숨김 파일을 제외합니다. 숨김 파일까지 필요하면 files(show_hidden_files=True)를 명시합니다.
R에서도 파일 속성 목록을 받아 다운로드하고 논리 이름으로 반복할 수 있습니다. 다음 예는 puppies의 모든 파일이 UTF-8 텍스트인 경우의 줄 수 계산입니다.
library(foundry)
all_files <- datasets.list_files("puppies")
downloaded_files <- datasets.download_files("puppies", all_files)
line_counts <- vapply(
downloaded_files,
function(local_path) {
length(readLines(local_path, warn = FALSE, encoding = "UTF-8"))
},
integer(1)
)
파일 형식이 서로 다르면 각 로컬 경로에 맞는 파서를 적용합니다. 반환된 경로를 데이터 이름이라고 간주하지 않습니다.
이름과 크기로 다운로드 제한
표 형식과 비정형 데이터셋 모두 원본 파일을 다운로드할 수 있습니다. 경로, 바이트 크기, 트랜잭션 RID와 수정 시각 등의 파일 메타데이터로 대상을 고릅니다.
Python에서 파일 하나를 지정할 수 있습니다.
from foundry.transforms import Dataset
local_file = Dataset.get("my_alias").files().get("file.pdf").download()
여러 파일은 개별 다운로드 호출을 반복하는 대신 FileCollection에 filter를 적용하면 병렬 다운로드를 이용할 수 있습니다. 다음은 .pdf로 끝나고 1 MiB, 즉 1,048,576바이트보다 작은 파일을 선택합니다.
from foundry.transforms import Dataset
pdf_files = (
Dataset.get("my_alias").files()
.filter(lambda file: file.path.endswith(".pdf") and file.size_bytes < 1024 * 1024)
.download()
)
R의 datasets.list_files는 path와 sizeBytes 등을 가진 파일 속성 목록을 반환합니다. datasets.download_files는 그 목록 또는 파일 경로 문자열을 받습니다.
library(foundry)
named_files <- datasets.download_files("my_alias", c("file1.pdf", "file2.pdf"))
R에서는 path에 endsWith를 적용하고 문자열로 제공될 수 있는 sizeBytes를 숫자로 변환합니다. 크기 정보가 없으면 이 조건을 판정할 수 없으므로 오류로 처리합니다.
library(foundry)
all_files <- datasets.list_files("my_alias")
pdf_files <- Filter(function(file) {
if (!endsWith(file$path, ".pdf")) {
return(FALSE)
}
size <- as.numeric(file$sizeBytes)
if (length(size) != 1L || is.na(size)) {
stop("sizeBytes metadata is required for the size filter")
}
size < 1024 * 1024
}, all_files)
downloaded_files <- datasets.download_files("my_alias", pdf_files)
경로 정규식으로 제한할 때는 datasets.list_files("my_alias", regex = ".*\\.pdf")를 사용할 수도 있습니다. 작업공간에서 제공한 SDK를 사용하며, 이미 다운로드한 뒤에 크기를 검사하는 것과 다운로드 전에 메타데이터로 제한하는 것을 구분합니다.