
lazy table to query parquet files at URLs, on R2 or S3, or at local paths
Source:R/parquet.R
parquet_tbl.RdLazy dplyr table on DuckDB for parquet files at public URLs (like public buckets or presigned URLs), in
private buckets on R2 as r2://bucket/path or on S3 as s3://bucket/path, or at local paths. Nothing gets
downloaded until the query is executed, e.g. via dplyr::collect(), and then only what the query needs:
filters on partition columns restrict which files get read, other filters and the selected columns which
parts of the files.
Usage
parquet_tbl(
path,
hive_partitioning = TRUE,
con = NULL,
cache = NULL,
language = getOption("r2parquet.language")
)Arguments
- path
URL,
r2://bucket/path,s3://bucket/pathor local path of a parquet file or a directory of (partitioned) parquet files, or a vector of these.- hive_partitioning
TRUE(default) orFALSE: derive partition columns fromkey=valuecomponents of the file paths. This includes the directories above a single file, so readingdata/year=2021/data_0.parquetadds ayearcolumn. Partition values are read as strings, whatever they look like, soPRUID=01andPRUID=10give the same type; onparquet_connection(), numbers compared with a partition column for equality (==,!=,%in%) are rendered as strings, with a message once per session, so thatfilter(year == 2021)only reads that partition. Order comparisons need the cast spelled out,as.integer(year) > 2020, since strings compare lexicographically.- con
DuckDB connection to create the table on. Tables can only be joined when they are on the same connection.
NULL(default):parquet_connection(), shared by all calls.a connection of your own, to join with data that lives there. The
httpfsandspatialextensions get installed and loaded on it as needed, and the R2 or S3 credentials get registered as secrets.
- cache
how to use the local cache (see the Cache section):
NULL(default): read the cached copy if it is current, else the remote files, with a warning for copies that are out of date. A copy only gets checked the first time its path is read in the session, later calls reuse the result (seeclear_cache_checks()).TRUE: update the copy first viacache_parquet(), downloading the files on first use, and read it.FALSE: read the remote files directly."offline": read the copy without checking it against the remote files, current or not; fails for paths without a copy.
- language
language code like
"en"or"fr", orNULL: with a language, the columns the data holds in several languages get selected in that language under their plain names, see the Languages section. Defaults to ther2parquet.languageoption.
Details
dplyr verbs get translated to SQL. Use sf::st_filter() to filter by
location, collect_parquet() to collect the result with its metadata attached (as an sf object if it has
geometry), parquet_metadata() for the metadata of the files and list_parquet() to list them. Tables
with GEOMETRY columns, like GeoParquet files written by data_to_parquet(), get the spatial extension
loaded, so that spatial functions like ST_Area work in queries.
Directories
Local directories and directories on R2 and S3 get read as all parquet files within them. Directories in buckets are often named like a parquet file, e.g.
r2://bucket/data.parquet, which works too.Directories at URLs can't be listed, they get read through the manifest next to their files (
_manifest.json, written byupload_parquet(),data_to_parquet()andwrite_manifest()). A URL ending in a slash is read as a directory; a URL without one is read as a file first and, if there is no file at it, as a directory.
Integer literals
Whole numbers in comparisons (==, !=, <, <=, >, >=, %in%, between) get rendered as
integers, with a message the first time in a session. A plain number like 2021 is a double in R, which
dplyr renders as 2021.0, and DuckDB resolves that against an integer column by casting the column,
which defeats the statistics it uses to skip row groups, so the filter downloads the whole column.
Comparisons with double columns are unaffected, and arithmetic is not rewritten (x * 1000 stays a double
multiplication). Write integers as 2021L to avoid the message, and on a connection of your own passed as
con, which keeps DuckDB's own translation.
Languages
Datasets can carry labels and columns in several languages, see the Languages section of
collect_parquet(). With a language the table gets its columns selected in that language through
select_language(): a column in the language asked for takes the place and name of its plain column,
name_fr becomes name, or stands in for a plain column the data doesn't have, and the columns in the
other languages get left out before anything is read, so a bilingual dataset read with
options(r2parquet.language = "fr") has name and no name_en. Which suffixes are languages is declared
by the metadata of the files (see the Languages section of data_to_parquet()), which gets read once
per table for this. The column names of the table
therefore depend on the language. language = NULL gives the columns as stored, for selecting them by
hand or with select_language() later, which also works on joins of such tables.
Errors
Paths without parquet files and denied requests fail with an error naming the path, of class
r2parquet_not_found or r2parquet_access_denied (both also r2parquet_error) for use with
tryCatch(). Denied requests say what access depends on: the credentials for buckets, the expiry of
presigned URLs, public access for other URLs. Servers that can't be reached, e.g. offline, fail with an
r2parquet_network_error, as does installing a DuckDB extension the first time it is needed. The
files get read when the query is executed, collect_parquet() raises the same errors then, e.g. when the
connection dropped after the table was created.
Cache
Remote files that get queried regularly can be kept in a local cache directory via cache_parquet(), and
the table then reads the local copies, see the cache argument. The default costs nothing for paths
without a copy, they are read remotely without any request to check them. With the default and with
cache = TRUE a cached copy gets used, with a warning, when the remote can't be reached, e.g. offline.
cache = "offline" also allows comparing the copy with the current remote files (cache = FALSE) before
updating it. Directories at public URLs can only be cached if they have a manifest. The cache directory is
the one in the R2PARQUET_CACHE_PATH environment variable, or the user cache directory if that is not set.
Credentials
Credentials come from environment variables, e.g. set in .Renviron, read at call time. Public URLs and
local paths need none.
Paths on R2 (r2://bucket/path):
R2_ACCOUNT_ID: the R2 account id.R2_ACCESS_KEY_IDandR2_SECRET_ACCESS_KEY: the access key id and secret access key of an R2 API token with access to the bucket.R2_API_TOKEN, optional: the value of an API token with Zone Cache Purge permission (seecreate_r2_bucket()). Files that change on R2 then get purged from the Cloudflare cache of the bucket's custom domains, so that the new versions are served right away; the purge is skipped without it.R2PARQUET_PURGE_ORIGINS, optional: the origins of web pages reading the bucket from a browser, comma separated, likehttps://example.com,https://www.example.com. Cloudflare caches the responses to their requests separately perOrigin, which a purge of the plain URL misses, so each changed file also gets purged once per origin; copies cached for origins not listed are refreshed when the edge TTL runs out. This only concerns web apps, whose browsers send theOriginheader; requests without one, like those of this package, DuckDB or curl, get the plain URL's copy, which is always purged.
Paths on S3 (s3://bucket/path), on Amazon S3 or another S3 compatible service like MinIO, use the
variables AWS tools use:
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY, andAWS_SESSION_TOKENfor temporary credentials.AWS_REGIONorAWS_DEFAULT_REGION: the region, defaultus-east-1.AWS_ENDPOINT_URL_S3orAWS_ENDPOINT_URL: the endpoint of other S3 compatible services, likehttp://localhost:9000, which get addressed with path style URLs (endpoint/bucket/key).R2PARQUET_S3_URL_STYLE:pathorvhost, overrides the URL style.
AWS profiles and single sign-on are not read, aws configure export-credentials --format env prints the
variables for them.