A unified database interface for Google Sheets, Excel, and CSV.
Project description
py-db-sheet: Local SQL Database with Bidirectional Sheet Sync
A Python library that gives you a fast local SQLite database with on-demand bidirectional sync to Google Sheets, Excel, or CSV.
Work entirely offline with a real SQL database. When you're ready, push your full DB state to a sheet — or pull from a sheet to repopulate your DB from scratch.
How it works
db → one file / spreadsheet / folder (the remote)
table → one sheet / tab inside that file
schema → __schema__ sheet in the same file (enables reconstruction)
- Local: All CRUD hits SQLite — instant and offline-capable.
- Push:
db.push_to_remote()dumps every table + schema to the linked remote. - Pull:
db.pull_from_remote()wipes local and repopulates from the remote, reconstructing typedSchemaobjects automatically.
Installation
pip install py-sheet-db
# or from source:
pip install -e .
Dependencies: gspread, google-auth, pandas, openpyxl
Quick Start
from py_sheet_db import PySheetDB, Schema
# 1. Initialize local SQLite database
db = PySheetDB("my_db")
# 2. Link a remote (CSV folder, Excel file, or Google Sheets)
db.link_remote("my_csv_backup", driver_type="csv")
# db.link_remote("my_backup.xlsx", driver_type="excel")
# db.link_remote("credentials.json", driver_type="gsheets", spreadsheet_id="YOUR_ID")
# 3. Define tables with optional typed schemas
schema = Schema({"id": int, "name": str, "score": float})
players = db.table("Players", schema=schema)
# 4. Normal SQL-style CRUD — all local, all fast
players.insert({"id": 1, "name": "Alice", "score": 95.5})
players.insert({"id": 2, "name": "Bob", "score": 88.0})
alice = players.find_one(id=1)
all_players = players.find()
players.update({"id": 1}, {"score": 99.0})
players.delete(id=2)
# 5. Push local state to the remote whenever you want
db.push_to_remote()
# 6. Pull from remote to repopulate local DB from scratch
db.pull_from_remote() # also restores Schema types automatically
# 7. Release connections when done
db.close()
Google Sheets
Setup
# Helper constructor for GSheets
db = PySheetDB.connect_gsheets(
db_path="my_local_db",
credentials_path="credentials.json",
spreadsheet_id="YOUR_SPREADSHEET_ID",
)
db.push_to_remote() # save to sheet
db.pull_from_remote() # restore from sheet
Getting credentials
- Go to the Google Cloud Console.
- Enable Google Sheets API and Google Drive API.
- Create a Service Account under APIs & Services → Credentials.
- Download the JSON key file and save it as
credentials.json. - Share your spreadsheet with the service account email (Editor access).
Schema Validation & Foreign Keys
Schemas enforce types on insert, and they can also define Primary Keys and Foreign Keys (enforced by the underlying SQLite engine).
from py_sheet_db import Schema
# Users table
users_schema = Schema({
"id": int,
"name": str,
"email": str,
}, primary_key="id")
users = db.table("Users", schema=users_schema)
users.insert({"id": 1, "name": "Alice", "email": "alice@example.com"})
# Orders table referencing Users
orders_schema = Schema({
"id": int,
"user_id": int,
"total": float,
}, primary_key="id", foreign_keys={"user_id": "Users.id"})
orders = db.table("Orders", schema=orders_schema)
# This succeeds:
orders.insert({"id": 1, "user_id": 1, "total": 50.5})
# This raises sqlite3.IntegrityError (foreign key violation):
# orders.insert({"id": 2, "user_id": 99, "total": 10.0})
Supported types: int, float, str, bool
Remote layout
After a push_to_remote(), the remote file/spreadsheet will contain:
| Sheet / File | Contents |
|---|---|
Players |
All rows from the Players table |
Users |
All rows from the Users table |
__schema__ |
table, column, type — one row per field |
A subsequent pull_from_remote() reads __schema__ first, then repopulates each table with the correct Schema attached.
CRUD Reference
table = db.table("MyTable")
# Insert
table.insert({"col1": "val1", "col2": 42})
# Find all
rows = table.find()
# Find with filter
rows = table.find(col1="val1")
# Find one
row = table.find_one(col2=42)
# Update (query dict, updates dict)
table.update({"col2": 42}, {"col1": "new_val"})
# Delete
table.delete(col2=42)
# Get all rows
rows = table.get_all()
Relational Views (Joins & Filters)
orders = db.table("Orders")
products = db.table("Products")
order_details = db.view("OrderDetails", [orders, products]) \
.join(orders, products, on="product_id", how="left") \
.filter(lambda df: df[df["status"] == "completed"])
results = order_details.get_data()
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_sheet_db-0.2.1.tar.gz.
File metadata
- Download URL: py_sheet_db-0.2.1.tar.gz
- Upload date:
- Size: 12.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
447ebd857577db2fb28cbff4b0cb4b85c465c77998e0d2bf96b52b35c4fe5868
|
|
| MD5 |
586c85d3e926913398160aae49740e72
|
|
| BLAKE2b-256 |
33e57e9d5b7128e6aae25748c0fae43c98a7e64e229d40e2586de66e5bb019b9
|
Provenance
The following attestation bundles were made for py_sheet_db-0.2.1.tar.gz:
Publisher:
publish.yml on nishant-sg/py-db-sheet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_sheet_db-0.2.1.tar.gz -
Subject digest:
447ebd857577db2fb28cbff4b0cb4b85c465c77998e0d2bf96b52b35c4fe5868 - Sigstore transparency entry: 2047944731
- Sigstore integration time:
-
Permalink:
nishant-sg/py-db-sheet@cf01b6505838aaaa41b13534fe3724768403a00d -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/nishant-sg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cf01b6505838aaaa41b13534fe3724768403a00d -
Trigger Event:
push
-
Statement type:
File details
Details for the file py_sheet_db-0.2.1-py3-none-any.whl.
File metadata
- Download URL: py_sheet_db-0.2.1-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffe01bcd7d174e5647a38bbb7016dac959787cfe614fa910e3109d3d515db598
|
|
| MD5 |
cf228e77752f5f031bf46aca8243e588
|
|
| BLAKE2b-256 |
1c396096158a26270fd46efb832fc869201b1361f5f3a146658a650bf7f7c382
|
Provenance
The following attestation bundles were made for py_sheet_db-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on nishant-sg/py-db-sheet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_sheet_db-0.2.1-py3-none-any.whl -
Subject digest:
ffe01bcd7d174e5647a38bbb7016dac959787cfe614fa910e3109d3d515db598 - Sigstore transparency entry: 2047944773
- Sigstore integration time:
-
Permalink:
nishant-sg/py-db-sheet@cf01b6505838aaaa41b13534fe3724768403a00d -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/nishant-sg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cf01b6505838aaaa41b13534fe3724768403a00d -
Trigger Event:
push
-
Statement type: