Hi! Just wanted to let you know that we have sent the changes to Tableau, and the documentation should now be up to date! If you everspot anything else, please let us know!
Hey Olaf B.! The COPY ... TO does actually work. One catch is that a gsheets community extension can't be loaded in the MotherDuck UI, since MotherDuck only supports the core DuckDB extensions server-side. You can run it on the DuckDB CLI on your own machine as follows:
INSTALL gsheets FROM community;
LOAD gsheets;
CREATE SECRET (TYPE gsheet); -- opens a browser window to sign in
ATTACH 'md:';
COPY (SELECT * FROM my_db.main.my_table)
TO 'https://docs.google.com/spreadsheets/d/<sheet_id>/edit' (FORMAT gsheet);
The extension runs locally, pulls the rows from MotherDuck, and writes them to your sheet. If you want it to land on a specific tab, you can add sheet 'TabName', create_if_not_exists true to the options. Here are the docs for further reference. If you want it configured in the UI, you can set up a Flight. We have a ready-made recipe. It does the same COPY with OVERWRITE_SHEET TRUE, so re-running replaces the tab cleanly. This one needs a Google service account key, and the sheet shared with that service account's email as Editor. One thing: on the free plan, Flights run on demand (30 min of compute a day), and scheduled runs need a card on file, so out of the box this gives you a one-click export rather than an automatic nightly refresh. If it's an occasional export, I'd start with using the extension, since it's the fastest path. If you want it repeatable, the Flight is a more robust way to go. We do have an open feature request to support the Google Sheets extension directly in MotherDuck. I've added your name to it so you'll be counted when it's prioritised.
Hey Greg! Nothing has changed on this since August, so the two approaches I described then are still the only paths: the zero-copy clone via a share, or moving the database to a service account that all writers authenticate as. Your request is tracked internally with your DuckLake case attached to it, and it is currently logged as a quality-of-life improvement. If it is costing you more than that, tell me what it blocks on your side, and I will add that to the request!
Hi Greg,
To address your points in order:
Is ownership transfer of a database between accounts in the same org supported?
There's no inherent 'ownership transfer' functionality, but there are two workaround approaches depending on your goal:
• Clone for independent work
If the new account wants their own writable copy of the database, you can create a share, which the new account then attaches. The new database can be created from an attached share by name or by using the share URL.
Here is an example of creating a zero-copy clone of sample_data:
-- attach to sample_data if not already attached
ATTACH IF NOT EXISTS 'md:_share/sample_data_db/9900037d-113c-4c34-be55-841596e3b7a3' AS sample_data;
-- create new db called my_sample_data
CREATE DATABASE my_sample_data FROM sample_data;
• Shared service account Create a service account (SA), move the database to it (using the instructions above), and have all writers authenticate using that SA access token. You can also impersonate this SA through the UI. This lets multiple people write to the same database without tying ownership to any one person's login.
Have we missed an alternative? Is there any way to grant write access to a non-owner account without transferring ownership?
Generally speaking, only the database owner account has write access to the database (single-writer architecture), so the approaches above are the only way to circumvent it.
What happens to existing shares when ownership moves? Do the shares + grants survive, do recipients need to re-ATTACH, and do the share URLs change?
Unfortunately, everything will have to be recreated; the share URLs will change, and recipients would need to reattach.
Is the transfer atomic? Is the DB still readable/writable during it? Rough duration for a database in the tens of GB?
Both depend on the 'transfer' approach you will be using. Zero-copy clone via CREATE DATABASE new_db FROM share is a metadata-only operation - it completes almost instantly regardless of database size. During the copy, the source remains readable and writable, but the operation is not atomic.
Is it reversible (can we transfer ownership back if needed)?
Yes, but in the same way you 'transferred' it originally.
One of the databases is a BYOB DuckLake catalog on Cloudflare R2. Does the new owner need its own R2 storage secret, and does anything about the DuckLake metadata or data paths need to change? (We’ve already learned that shares don’t convey the storage credential — consumers can read catalog metadata fine but 404 on the underlying parquet without their own r2 secret.)
Yes, the new owner will need their own R2 storage secret (CREATE SECRET with their R2 credentials scoped to DuckLake's DATA_PATH). Shares do not convey storage credentials, as you've noted.
However, the standard CREATE DATABASE FROM share zero-copy clone path is designed for MotherDuck native databases and does not natively support DuckLake databases in the same way. For a BYOB DuckLake, the data paths and metadata structure are different, and the share-to-clone workflow won't work. The best way would be to create a new DuckLake on the new SA, and then load the parquet data from the bucket you control (with this function). It's a metadata-only operation, but you will need to do it manually.
We have the database/lake ownership transfer tracked as a feature request internally, and can get back to you when there's a dedicated feature for that!
Would this answer your questions? I'd be happy to elaborate further!
Unfortunately, that would not be possible at the moment 😔 I can flag it as a feature request, though, would you like me to?
Good luck! If you have any questions in the meantime, feel free to drop them here too 🙂↕️
.png)