tursodatabase / libsql-experimental-python

libSQL API for Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Commit behavior is different between local and remote

penberg opened this issue · comments

Python SQLite interface expects caller to call commit() explicitly but @avinassh points out this does not work with remote databases:

ValueError: Hrana: `stream error: `StreamResponseError { error: Error { message: "SQLite error: cannot commit - no transaction is active" } }``

I am guessing the remote protocol semantics with is_autocommit() are wrong in libsql crate.

here is a simple reproducer:

import os

import libsql_experimental as libsql

print(F"connecting to {os.getenv('LIBSQL_URL')}")
conn = libsql.connect(database=os.getenv('LIBSQL_URL'), sync_url=os.getenv("LIBSQL_URL"),
                      auth_token=os.getenv("LIBSQL_AUTH_TOKEN"))
conn.execute("CREATE TABLE IF NOT EXISTS users_sync (id INTEGER);")
conn.execute("INSERT INTO users_sync(id) VALUES (10);")
conn.commit()

print(conn.execute("select * from users_sync").fetchall())

I'm getting the same error in Go. Some more info based off the below code:

  1. If you remove the SELECT * FROM users_sync chunk of code it works fine. And it returns the proper results if you move that SELECT out of the transaction.
  2. It works fine against a sqld image running in Docker just fine.
package main

import (
	"context"
	"database/sql"
	"fmt"
	"os"

	_ "github.com/tursodatabase/libsql-client-go/libsql"
)

func main() {
	db, err := sql.Open("libsql", os.Getenv("LIBSQL_URL"))
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to open db %s", err)
		os.Exit(1)
	}
	defer db.Close()

	tx, err := db.BeginTx(context.Background(), &sql.TxOptions{})
	if err != nil {
		panic(err)
	}

	_, err = tx.Exec("CREATE TABLE IF NOT EXISTS users_sync (id INTEGER)")
	if err != nil {
		panic(err)
	}

	_, err = tx.Exec("INSERT INTO users_sync(id) VALUES (10)")
	if err != nil {
		panic(err)
	}

	rows, err := tx.Query("SELECT * FROM users_sync")
	if err != nil {
		panic(err)
	}
	defer rows.Close()

	for rows.Next() {
		var id int

		if err := rows.Scan(&id); err != nil {
			fmt.Println("Error scanning row:", err)
			return
		}

		fmt.Println("id:", id)
	}

	err = tx.Commit()
	if err != nil {
		panic(err)
	}
}

And I confirmed with my project code where I'm getting this during my account provisioning routine that if I remove all of the selects I don't get this error.