Skip to content

Change hard-coded base api url to config or env variable #22

Description

@jeff-phil

The base URL for cloudflare endpoint is hard-coded here:

https://github.com/CollierKing/sqlalchemy-cloudflare-d1/blob/main/src/sqlalchemy_cloudflare_d1/connection.py#L479

This has two downsides of making d1 local development difficult, and secondly will likely require future changes when cloudflare updates their endpoint.

For local development, I currently use a simple local d1 proxy that ignores account id, api key, database, etc. passed into the service.

Here's the src/index.js file:

export default {
  async fetch(request, env) {
    // Only accept POST requests
    if (request.method !== "POST") {
      return new Response("Method not allowed", { status: 405 });
    }

    try {
      // Expects an array: [{ "sql": "INSERT...", "params": ["Alice"] }]
      const queries = await request.json();
      console.log(queries);

      // Convert the JSON payload into D1 Prepared Statements
      const statements = queries.map(query => {
        let stmt = env.DB.prepare(query.sql);
        // Bind parameters if they exist
        if (query.params && Array.isArray(query.params) && query.params.length > 0) {
          stmt = stmt.bind(...query.params);
        }
        return stmt;
      });

      // Execute all statements in a single batch (this acts as a local transaction)
      const results = await env.DB.batch(statements);

      // Return the results to FastAPI
      return Response.json({ success: true, result: results });

    } catch (error) {
      return Response.json({ success: false, error: error.message }, { status: 500 });
    }
  }
};

and the wrangler.toml

name = "d1-local-proxy"
main = "src/index.js"
compatibility_date = "2025-08-22"

# This block is what magically connects `env.DB` in JS to your local database
[[d1_databases]]
binding = "DB"
database_name = "my-local-db"
database_id = "ffffffff-4242-4242-4242-ffffffffffff"

And run with something like wrangler dev --persist-to ../local-dbs to start the http service that interacts with the local D1 service that runs on http://localhost:8787

I then in my own code use base = os.getenv("CF_D1_BASE_URL") to get the overriding http://localhost:8787 local endpoint, and when not set uses the default cloudflare endpoint.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions