Public
Edited
Jan 2
6 forks
Insert cell
Insert cell
client
select * from penguins
-- select * from iris
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
db_instance.getVersion()
Insert cell
duckdb = import(
"https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm@1.28.1-dev232.0/+esm"
)
Insert cell
bundle = {
const bundles = duckdb.getJsDelivrBundles()
if (duckdb_bundle === 'Auto') {
return duckdb.selectBundle(bundles)
} else {
const bun = bundles[duckdb_bundle]
bun['pthreadWorker'] = null;
return bun;
}
// return bundles['mvp']
}
Insert cell
async function makeDB() {
const logger = new duckdb.ConsoleLogger();
const worker = await duckdb.createWorker(bundle.mainWorker);
const db = new duckdb.AsyncDuckDB(logger, worker);
await db.instantiate(bundle.mainModule);
return db
}
Insert cell
db_instance = {
// Initialize database
const db = await makeDB()

// Insert files directly into tables
await insertFile(db, 'penguins_file', penguins_file);

// Alternatively, register file into the db's filesystem
const iris_buffer = await iris_file.arrayBuffer();
await db.registerFileBuffer(
'iris.csv', // Choose filename to use inside db
new Uint8Array(iris_buffer)
);
return db
}
Insert cell
client = {
const client_class = (duckdb_client === 'Compatibility') ? DuckDBClientCompat : DuckDBClient;
const c = new client_class(db_instance);

// Create tables here
await c.query(`
create or replace table penguins as (
from penguins_file
)
`)
await c.query(`
create or replace table iris as (
from 'iris.csv' -- Filename used as first arg to db.registerFileBuffer
)
`)
return c;
}
Insert cell
Insert cell
class DuckDBClientCompat extends DuckDBClient {
async queryStream(query, params) {
const connection = await this._db.connect();
let reader, batch;
try {
if (params?.length > 0) {
const statement = await connection.prepare(query);
reader = await statement.send(...params);
} else {
reader = await connection.send(query);
}
batch = await reader.next();
if (batch.done) throw new Error("missing first batch");
} catch (error) {
await connection.close();
throw error;
}

// Mosaic utility: convert Arrow value to Javascript value
const converters = {}
batch.value.schema.fields.forEach(d => {
console.log('Type for ', d.name, d.type)
converters[d.name] = convertArrowValue(d.type)
})
return {
schema: getArrowTableSchema(batch.value),
async *readRows() {
try {
while (!batch.done) {
let batch_array = batch.value.toArray();

// Convert all values to Javascript version
let object_array = []
for (let i = 0; i < batch_array.length; i++) {
const d_proxy = batch_array[i];
const d_obj = {}
for (let k of Object.keys(converters)) {
d_obj[k] = converters[k](d_proxy[k])
}
object_array.push(d_obj)
}
yield object_array;
batch = await reader.next();
}
} finally {
await connection.close();
}
}
};
}
}
Insert cell
Insert cell
Insert cell
getArrowTableSchema = observable_stdlib.getArrowTableSchema
Insert cell
convertArrowValue = mosaic_core.convertArrowValue
Insert cell
observable_stdlib = await import('https://cdn.jsdelivr.net/npm/@observablehq/stdlib@5.8.7/+esm');
Insert cell
mosaic_core = await import('https://cdn.jsdelivr.net/npm/@uwdata/mosaic-core@0.9.0/+esm');
Insert cell
Insert cell
penguins_file = FileAttachment("penguins.csv")
Insert cell
iris_file = FileAttachment("iris.csv")
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more