From 67ef5deee9253c00c34a39baacd43514e16a7d8a Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 28 Nov 2025 15:00:19 +0000 Subject: [PATCH 1/2] Adds Python tabs to d1/worker-api pages. --- .../docs/d1/worker-api/d1-database.mdx | 151 +++++++++++++++-- .../d1/worker-api/prepared-statements.mdx | 159 ++++++++++++++++-- .../docs/d1/worker-api/return-object.mdx | 26 ++- 3 files changed, 310 insertions(+), 26 deletions(-) diff --git a/src/content/docs/d1/worker-api/d1-database.mdx b/src/content/docs/d1/worker-api/d1-database.mdx index 4fa355f349b4ff9..f8268147c26e089 100644 --- a/src/content/docs/d1/worker-api/d1-database.mdx +++ b/src/content/docs/d1/worker-api/d1-database.mdx @@ -5,15 +5,26 @@ sidebar: order: 1 --- -import { Type, MetaInfo, Details } from "~/components"; +import { Type, MetaInfo, Details, Tabs, TabItem } from "~/components"; To interact with your D1 database from your Worker, you need to access it through the environment bindings provided to the Worker (`env`). + ```js async fetch(request, env) { // D1 database is 'env.DB', where "DB" is the binding name from the Wrangler configuration file. } ``` + +```py +from workers import WorkerEntrypoint + +class Default(WorkerEntrypoint): + async def fetch(self, request): + # D1 database is 'self.env.DB', where "DB" is the binding name from the Wrangler configuration file. + pass +``` + A D1 binding has the type `D1Database`, and supports a number of methods, as listed below. @@ -23,10 +34,17 @@ A D1 binding has the type `D1Database`, and supports a number of methods, as lis Prepares a query statement to be later executed. + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); ``` + +```py +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +``` + #### Parameters @@ -44,18 +62,30 @@ You can use the `bind` method to dynamically bind a value into the query statem - Example of a static statement without using `bind`: + ```js const stmt = db .prepare("SELECT * FROM Customers WHERE CompanyName = Alfreds Futterkiste AND CustomerId = 1") ``` + + ```py + stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = Alfreds Futterkiste AND CustomerId = 1") + ``` + - Example of an ordered statement using `bind`: + ```js const stmt = db .prepare("SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?") .bind("Alfreds Futterkiste", 1); ``` + + ```py + stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?").bind("Alfreds Futterkiste", 1) + ``` + Refer to the [`bind` method documentation](/d1/worker-api/prepared-statements/#bind) for more information. @@ -67,6 +97,7 @@ Batched statements are [SQL transactions](https://www.sqlite.org/lang_transactio To send batch statements, provide `D1Database::batch` a list of prepared statements and get the results in the same order. + ```js const companyName1 = `Bs Beverages`; const companyName2 = `Around the Horn`; @@ -76,6 +107,19 @@ const batchResult = await env.DB.batch([ stmt.bind(companyName2) ]); ``` + +```py +from pyodide.ffi import to_js + +company_name1 = "Bs Beverages" +company_name2 = "Around the Horn" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?") +batch_result = await self.env.DB.batch(to_js([ + stmt.bind(company_name1), + stmt.bind(company_name2) +])) +``` + #### Parameters @@ -90,6 +134,7 @@ const batchResult = await env.DB.batch([
+ ```js const companyName1 = `Bs Beverages`; const companyName2 = `Around the Horn`; @@ -99,7 +144,22 @@ const stmt = await env.DB.batch([ ]); return Response.json(stmt) ``` -```js output + +```py +from pyodide.ffi import to_js +from workers import Response + +company_name1 = "Bs Beverages" +company_name2 = "Around the Horn" +stmt = await self.env.DB.batch(to_js([ + self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(company_name1), + self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(company_name2) +])) +return Response.json(stmt) +``` + + +```json output [ { "success": true, @@ -148,10 +208,17 @@ return Response.json(stmt) } ] ``` + ```js console.log(stmt[1].results); ``` -```js output + +```py +print(stmt[1].results.to_py()) +``` + + +```json output [ { "CustomerId": 4, @@ -166,24 +233,46 @@ console.log(stmt[1].results); - You can construct batches reusing the same prepared statement: + ```js - const companyName1 = `Bs Beverages`; - const companyName2 = `Around the Horn`; - const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`); - const batchResult = await env.DB.batch([ - stmt.bind(companyName1), - stmt.bind(companyName2) - ]); - return Response.json(batchResult); + const companyName1 = `Bs Beverages`; + const companyName2 = `Around the Horn`; + const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`); + const batchResult = await env.DB.batch([ + stmt.bind(companyName1), + stmt.bind(companyName2) + ]); + return Response.json(batchResult); + ``` + + ```py + from pyodide.ffi import to_js + from workers import Response + + company_name1 = "Bs Beverages" + company_name2 = "Around the Horn" + stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?") + batch_result = await self.env.DB.batch(to_js([ + stmt.bind(company_name1), + stmt.bind(company_name2) + ])) + return Response.json(batch_result) ``` + ### `exec()` Executes one or more queries directly without prepared statements or parameter bindings. + ```js const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`); ``` + +```py +return_value = await self.env.DB.exec('SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"') +``` + #### Parameters @@ -198,11 +287,22 @@ const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName - Refer to [`D1ExecResult`](/d1/worker-api/return-object/#d1execresult) for more information.
+ + ```js const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`); return Response.json(returnValue); ``` -```js output + +```py +from workers import Response + +return_value = await self.env.DB.exec('SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"') +return Response.json(return_value) +``` + + +```json output { "count": 1, "duration": 1 @@ -225,6 +325,7 @@ This API only works on databases created during D1's alpha period. Check which v Dumps the entire D1 database to an SQLite compatible file inside an ArrayBuffer. + ```js const dump = await db.dump(); return new Response(dump, { @@ -234,6 +335,14 @@ return new Response(dump, { }, }); ``` + +```py +from workers import Response + +dump = await db.dump() +return Response(dump, status=200, headers={"Content-Type": "application/octet-stream"}) +``` + #### Parameters @@ -247,9 +356,15 @@ return new Response(dump, { Starts a D1 session which maintains sequential consistency among queries executed on the returned `D1DatabaseSession` object. -```ts + +```js const session = env.DB.withSession(""); ``` + +```py +session = self.env.DB.withSession("") +``` + #### Parameters @@ -283,13 +398,21 @@ const session = env.DB.withSession(""); Retrieves the latest `bookmark` from the D1 Session. -```ts + +```js const session = env.DB.withSession("first-primary"); const result = await session .prepare(`SELECT * FROM Customers WHERE CompanyName = 'Bs Beverages'`) .run() return { bookmark } = session.getBookmark(); ``` + +```py +session = self.env.DB.withSession("first-primary") +result = await session.prepare("SELECT * FROM Customers WHERE CompanyName = 'Bs Beverages'").run() +bookmark = session.getBookmark() +``` + #### Parameters diff --git a/src/content/docs/d1/worker-api/prepared-statements.mdx b/src/content/docs/d1/worker-api/prepared-statements.mdx index 38821b571be3420..0552b0fbf0898e7 100644 --- a/src/content/docs/d1/worker-api/prepared-statements.mdx +++ b/src/content/docs/d1/worker-api/prepared-statements.mdx @@ -5,7 +5,7 @@ sidebar: order: 2 --- -import { Type, MetaInfo, Details } from "~/components"; +import { Type, MetaInfo, Details, Tabs, TabItem } from "~/components"; This chapter documents the various ways you can run and retrieve the results of a query after you have [prepared your statement](/d1/worker-api/d1-database/#prepare). @@ -15,10 +15,19 @@ This chapter documents the various ways you can run and retrieve the results of Binds a parameter to the prepared statement. + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); ``` + +```py +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare( + "SELECT * FROM Customers WHERE CompanyName = ?" +).bind(some_variable) +``` + #### Parameter @@ -43,21 +52,42 @@ const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bin Order and anonymous examples: + ```js const stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(""); ``` + + ```py + stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind("") + ``` + + ```js const stmt = db .prepare("SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?") .bind("Alfreds Futterkiste", 1); ``` + + ```py + stmt = db.prepare( + "SELECT * FROM Customers WHERE CompanyName = ? AND CustomerId = ?" + ).bind("Alfreds Futterkiste", 1) + ``` + + ```js const stmt = db - .prepare("SELECT * FROM Customers WHERE CompanyName = ?2 AND CustomerId = ?1") - .bind(1, "Alfreds Futterkiste"); + .prepare( + "SELECT * FROM Customers WHERE CompanyName = ?2 AND CustomerId = ?1" + ).bind(1, "Alfreds Futterkiste"); + ``` + + ```py + stmt = db.prepare("SELECT * FROM Customers WHERE CompanyName = ?2 AND CustomerId = ?1").bind(1, "Alfreds Futterkiste") ``` + #### Static statements @@ -70,28 +100,51 @@ The recommended approach is to use [prepared statements](/d1/worker-api/d1-datab Example of a prepared statement with dynamically bound value: + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); // A variable (someVariable) will replace the placeholder '?' in the query. // `stmt` is a prepared statement. ``` + +```py +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +# A variable (some_variable) will replace the placeholder '?' in the query. +# `stmt` is a prepared statement. +``` + Example of a static statement: + ```js const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = Bs Beverages"); // "Bs Beverages" is hard-coded into the query. // `stmt` is a static statement. ``` + +```py +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = Bs Beverages") +# "Bs Beverages" is hard-coded into the query. +# `stmt` is a static statement. +``` + ### `run()` Runs the prepared query (or queries) and returns results. The returned results includes metadata. + ```js const returnValue = await stmt.run(); ``` + +```py +return_value = await stmt.run() +``` + #### Parameter @@ -104,15 +157,26 @@ const returnValue = await stmt.run(); - For more information on the object, refer to [`D1Result`](/d1/worker-api/return-object/#d1result).
+ + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); const returnValue = await stmt.run(); -``` -```js return Response.json(returnValue); ``` -```js output + +```py +from workers import Response + +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +return_value = await stmt.run() +return Response.json(return_value) +``` + + +```json output { "success": true, "meta": { @@ -149,10 +213,20 @@ return Response.json(returnValue); - You can choose to extract only the results you expect from the statement by simply returning the `results` property of the return object.
+ + ```js return Response.json(returnValue.results); ``` -```js output + +```py +from workers import Response + +return Response.json(return_value.results) +``` + + +```json output [ { "CustomerId": 11, @@ -174,9 +248,15 @@ Runs the prepared query (or queries), and returns the results as an array of arr Column names are not included in the result set by default. To include column names as the first row of the result array, set `.raw({columnNames: true})`. + ```js const returnValue = await stmt.raw(); ``` + +```py +return_value = await stmt.raw() +``` + #### Parameters @@ -189,13 +269,26 @@ const returnValue = await stmt.raw(); - An array of arrays. Each sub-array represents a row.
+ + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); const returnValue = await stmt.raw(); return Response.json(returnValue); ``` -```js output + +```py +from workers import Response + +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +return_value = await stmt.raw() +return Response.json(return_value) +``` + + +```json output [ [11, "Bs Beverages", "Victoria Ashworth" @@ -207,13 +300,27 @@ return Response.json(returnValue); ``` With parameter `columnNames: true`: + + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); const returnValue = await stmt.raw({columnNames:true}); return Response.json(returnValue) ``` -```js output + +```py +from pyodide.ffi import to_js +from workers import Response + +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +return_value = await stmt.raw(columnNames=True) +return Response.json(return_value) +``` + + +```json output [ [ "CustomerId", @@ -238,9 +345,15 @@ return Response.json(returnValue) Runs the prepared query (or queries), and returns the first row of the query result as an object. This does not return any metadata. Instead, it directly returns the object. + ```js const values = await stmt.first(); ``` + +```py +values = await stmt.first() +``` + #### Parameters @@ -262,13 +375,25 @@ const values = await stmt.first(); Get all the columns from the first row: + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); const returnValue = await stmt.first(); return Response.json(returnValue) ``` -```js output + +```py +from workers import Response + +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +return_value = await stmt.first() +return Response.json(return_value) +``` + + +```json output { "CustomerId": 11, "CompanyName": "Bs Beverages", @@ -278,13 +403,25 @@ return Response.json(returnValue) Get a specific column from the first row: + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); const returnValue = await stmt.first(CustomerId); return Response.json(returnValue) ``` -```js output + +```py +from workers import Response + +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +return_value = await stmt.first("CustomerId") +return Response.json(return_value) +``` + + +```json output 11 ```
diff --git a/src/content/docs/d1/worker-api/return-object.mdx b/src/content/docs/d1/worker-api/return-object.mdx index 5fc5a22ff7c8e7f..3b5c6c4f0ede78e 100644 --- a/src/content/docs/d1/worker-api/return-object.mdx +++ b/src/content/docs/d1/worker-api/return-object.mdx @@ -5,6 +5,8 @@ sidebar: order: 3 --- +import { Tabs, TabItem } from "~/components"; + Some D1 Worker Binding APIs return a typed object. | D1 Worker Binding API | Return object | @@ -45,12 +47,24 @@ The methods [`D1PreparedStatement::run`](/d1/worker-api/prepared-statements/#run ### Example + ```js const someVariable = `Bs Beverages`; const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(someVariable); const returnValue = await stmt.run(); return Response.json(returnValue) ``` + +```py +from workers import Response + +some_variable = "Bs Beverages" +stmt = self.env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bind(some_variable) +return_value = await stmt.run() +return Response.json(return_value) +``` + + ```json { "success": true, @@ -100,11 +114,21 @@ The method [`D1Database::exec`](/d1/worker-api/d1-database/#exec) returns a type ### Example + ```js const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`); return Response.json(returnValue); ``` -```js output + +```py +from workers import Response + +return_value = await self.env.DB.exec('SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"') +return Response.json(return_value) +``` + + +```json output { "count": 1, "duration": 1 From 1260a2cbb82734e1876e50f898f46ec0947657d1 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 2 Dec 2025 16:37:28 +0000 Subject: [PATCH 2/2] Apply suggestion from @hoodmane Co-authored-by: Hood Chatham --- src/content/docs/d1/worker-api/d1-database.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/content/docs/d1/worker-api/d1-database.mdx b/src/content/docs/d1/worker-api/d1-database.mdx index f8268147c26e089..f4ed600318b2fb5 100644 --- a/src/content/docs/d1/worker-api/d1-database.mdx +++ b/src/content/docs/d1/worker-api/d1-database.mdx @@ -409,7 +409,10 @@ return { bookmark } = session.getBookmark(); ```py session = self.env.DB.withSession("first-primary") -result = await session.prepare("SELECT * FROM Customers WHERE CompanyName = 'Bs Beverages'").run() +result = await session.prepare( + "SELECT * FROM Customers WHERE CompanyName = 'Bs Beverages'" +).run() + bookmark = session.getBookmark() ```