gdrive

Dateien in Google Drive direkt über ein gdrive://-Dateisystem abfragen

Maintainer: jrosskopf

Installation und Laden

INSTALL gdrive FROM community;
LOAD gdrive;

Beispiel

-- Unattended: a service account. To WRITE you need a Shared Drive --
-- service accounts have no personal Drive storage quota and get
-- 403 storageQuotaExceeded anywhere else. Reading a shared folder is fine.
--
-- DRIVE_ID is a SHARED DRIVE id; ROOT_FOLDER_ID is a FOLDER id. They are
-- not interchangeable: passing a folder id as DRIVE_ID fails with
-- "Shared drive not found". Use whichever matches what was shared.
CREATE SECRET gdrive (
TYPE gdrive,
PROVIDER service_account,
KEY_FILE '/etc/creds/sa.json',
DRIVE_ID '0ABcDeFgHiJkLmNoPQ', -- or ROOT_FOLDER_ID '1a2b3c...'
DRIVE_SCOPE 'https://www.googleapis.com/auth/drive.readonly'
);
-- Query a file by path. Drive has no path addressing, so each segment
-- costs a lookup; results are cached per secret.
SELECT count(*) FROM 'gdrive://Finance/2026/actuals.parquet';
-- Address a file by id instead: zero resolution calls. Prefer this in
-- generated or stored queries.
SELECT * FROM read_csv('gdrive://id:1a2b3cDeFgHiJkLmNoPQrStUvWxYz');
-- Glob a folder.
SELECT * FROM read_parquet('gdrive://exports/parts/*.parquet');
-- A native Google Sheet is queryable with no manual export: it has no
-- byte stream, so it is served through Drive's CSV export.
SELECT * FROM read_csv('gdrive://Finance/Budget');
-- Write a whole file. Writes are sequential; Drive cannot write at a
-- byte offset, so positional writes raise an error rather than corrupt.
COPY (SELECT * FROM t) TO 'gdrive://reports/out.parquet' (FORMAT parquet);
-- Inspect API calls and cache hits for the session.
SELECT * FROM gdrive_stats();

Über gdrive

Registriert ein Dateisystem gdrive://, sodass jeder DuckDB-Pfadausdruck eine Datei in Google Drive ohne Download- oder Kopierschritt adressieren kann. Weil DuckDB den Dateizugriff über sein virtuelles Dateisystem dispatcht, erbt alles darauf Aufbauende das Schema: read_parquet, read_csv, COPY, glob und Tabellenformate wie DuckLake — das Anhängen eines DuckLake, dessen DATA_PATH auf Drive liegt, funktioniert und wird live getestet.

ATTACH einer DuckDB-Datenbankdatei auf gdrive:// wird NICHT unterstützt. DuckDB öffnet Datenbankdateien über einen anderen Pfad, der das virtuelle Dateisystem nicht konsultiert; der Versuch schlägt daher sofort fehl, statt nur halb zu funktionieren.

Das ist Google Drive, nicht Google Cloud Storage — ein anderes Produkt mit anderer API und anderem Zugriffsmodell. Für gs://-Buckets verwenden Sie die Erweiterung gcs.

Lesezugriffe sind bereichsweise, sodass ein Parquet-Scan Footer und Spaltenchunks statt ganzer Dateien holt. Die Pfadauflösung wird pro Secret und pro Drive gecacht, weil Drive keine Pfadressierung hat und jedes Segment sonst einen API-Aufruf kostet.

Zwei Verhaltensweisen sind bewusst streng. Drive erlaubt zwei Dateien mit demselben Namen in einem Ordner, daher ist ein Pfad kein eindeutiger Identifikator: statt eine auszuwählen und Ergebnisse von der internen Reihenfolge von Drive abhängig zu machen, ist Mehrdeutigkeit ein Fehler, der beide Datei-IDs nennt. Und Drive kann nicht an einem Byte-Offset schreiben, daher lösen positionale Schreibvorgänge einen Fehler aus, statt eine Datei still zu beschädigen.

Drive ist deutlich langsamer als Objektspeicher und erzwingt benutzerbezogene API-Kontingente, die Objektspeicher nicht hat. Ein Bereichslese kostet ~1,3 s unabhängig davon, wie wenige Bytes angefordert werden, gegenüber ~1 ms bei S3/GCS. Verwenden Sie dies, wenn Drive das System of Record für Daten ist, die Sie abfragen möchten, und Sie lieber keine zweite Kopie pflegen — nicht als Ersatz für Objektspeicher unter hoher Last. Auf einer Workstation sind Google Drive for desktop plus gewöhnliche lokale Pfade einfacher und schneller.

Hinzugefügte Funktionen

function_name function_type description comment examples
file_size scalar Byte length of the file at path, or NULL if it does not exist. Reads only metadata for ordinary files – unlike read_blob, which downloads the body. NOTE: a native Google Doc or Sheet has no stored byte size, so its size is the length of the EXPORT (see gdrive_docs_export_mime) and obtaining it downloads that export. Unlike read_blob(), which reports the same number but downloads the whole body to do it. NULL [SELECT file_size(‘gdrive://data/part.parquet’)]
gdrive_reset_stats table Zero the process-wide Drive API call counters reported by gdrive_stats(). Use it to measure exactly what ONE operation costs: reset, run the query, then read gdrive_stats(). Affects the whole process, so it will disturb a concurrent measurement in another connection. NULL [CALL gdrive_reset_stats()]
gdrive_stats table Drive API call counters, one row per metric: files_get, files_list, files_media, files_export, files_create, files_update, files_delete (calls by kind), cache_hits/cache_misses (the path-resolution cache that mitigates R-1 amplification), retries (retried HTTP attempts across all kinds), and total (sum of the files_* kind counters), and path_cache_entries (a GAUGE: the live size of the path->id cache, bounded by gdrive_path_cache_entries). Process-wide, not reset between queries – call it before and after an operation and diff the two snapshots to measure that operation’s amplification. NULL [SELECT * FROM gdrive_stats()]
gdrive_version scalar NULL NULL
move_file scalar Rename/move source to target, returning true on success and raising on failure. Dispatches on the path’s scheme through DuckDB’s virtual filesystem. Both paths must live on the SAME filesystem – this is a rename, not a copy, and it does not move bytes between schemes. Its main use is publishing a fully-written temporary file under its final name. NULL [SELECT move_file(‘gdrive://staging/part.tmp’, ‘gdrive://data/part.parquet’)]
remove_file scalar Delete the file at path, returning true if it existed and was removed and false if it did not exist. Dispatches on the path’s scheme through DuckDB’s virtual filesystem, so it works for gdrive://, s3://, gs:// and local paths alike. For a gdrive:// path the file is moved to the trash unless gdrive_permanent_delete is set. Errors other than not-found are raised, not returned as false. NULL [SELECT remove_file(‘gdrive://reports/old.parquet’)]
write_blob scalar Write content to path, replacing any existing file, and return the number of bytes written. The inverse of read_blob(): together they give SQL a byte-exact round trip for any filesystem DuckDB can reach, including gdrive://, with no CSV/Parquet encoding in between. Accepts arbitrary binary content – a BLOB, not a VARCHAR – so it is safe for images and PDFs as well as text. NULL [SELECT write_blob(‘gdrive://notes/readme.md’, ‘# Title’::BLOB)]

Überladene Funktionen

Diese Erweiterung fügt keine Funktionsüberladungen hinzu.

Hinzugefügte Typen

Diese Erweiterung fügt keine Typen hinzu.

Hinzugefügte Einstellungen

name description input_type scope aliases
datazoo_banner Show the DataZoo feedback banner when an extension is loaded in an interactive terminal (at most once a day per extension). BOOLEAN GLOBAL []
gdrive_adc_file Path to an Application Default Credentials JSON file, overriding normal discovery for PROVIDER credential_chain. Empty (default) resolves GOOGLE_APPLICATION_CREDENTIALS, then CLOUDSDK_CONFIG, then the well-known gcloud location. VARCHAR GLOBAL []
gdrive_block_cache_bytes Total memory the shared block cache may hold (default 256 MiB). Least-recently-used blocks are evicted above this. Shared by all files and all threads. UBIGINT GLOBAL []
gdrive_block_size_bytes Block size for cached reads (default 16 MiB, 0 to disable and read exact ranges). Drive charges roughly the same for a 1 KB and a 16 MB request, so larger blocks trade bandwidth for far fewer round trips. UBIGINT GLOBAL []
gdrive_docs_export_mime MIME type to export application/vnd.google-apps.document files as: ‘text/plain’ (default) or ‘text/markdown’. Sheets always export to text/csv. VARCHAR GLOBAL []
gdrive_immutable_prefixes Comma-separated gdrive:// path prefixes whose files are never overwritten in place (e.g. a DuckLake DATA_PATH). Skips the per-open metadata refresh for them. Matching is on whole path segments. Empty (the default) disables it. Declaring a prefix whose files ARE rewritten in place causes stale reads that cannot be detected. VARCHAR GLOBAL []
gdrive_path_cache_entries Maximum path->file-id mappings to cache (default 4096, 0 for unbounded). Least-recently-used entries are dropped above this; a dropped mapping just costs one files.list per segment to rebuild. UBIGINT GLOBAL []
gdrive_permanent_delete RemoveFile permanently deletes instead of moving to trash (default: false, trash). BOOLEAN GLOBAL []