{"id":31640005,"url":"https://github.com/jonaylor89/sheetsql","last_synced_at":"2025-10-07T02:08:58.964Z","repository":{"id":303068933,"uuid":"1014291682","full_name":"jonaylor89/sheetsql","owner":"jonaylor89","description":"Query Google Sheets with SQL","archived":false,"fork":false,"pushed_at":"2025-07-07T13:51:38.000Z","size":45,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-16T13:17:48.764Z","etag":null,"topics":["golang","google-sheets","orm","sql"],"latest_commit_sha":null,"homepage":"https://blog.jonaylor.com/query-google-sheets-with-sql","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonaylor89.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-05T12:29:01.000Z","updated_at":"2025-07-07T13:51:41.000Z","dependencies_parsed_at":"2025-07-05T14:18:42.067Z","dependency_job_id":"dd5ba49b-863f-4932-85e6-e7e96a40f36f","html_url":"https://github.com/jonaylor89/sheetsql","commit_stats":null,"previous_names":["jonaylor89/sheetsql"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jonaylor89/sheetsql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2Fsheetsql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2Fsheetsql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2Fsheetsql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2Fsheetsql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonaylor89","download_url":"https://codeload.github.com/jonaylor89/sheetsql/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2Fsheetsql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278708004,"owners_count":26031932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","google-sheets","orm","sql"],"created_at":"2025-10-07T02:08:41.666Z","updated_at":"2025-10-07T02:08:58.954Z","avatar_url":"https://github.com/jonaylor89.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SheetSQL\n\nA Go ORM for Google Sheets that allows you to query and manipulate Google Sheets data using both a fluent API and SQL-like syntax.\n\n## Features\n\n- **Fluent API**: Chainable query builder similar to popular Go ORMs\n- **SQL Support**: Write raw SQL queries against Google Sheets\n- **Struct Mapping**: Map sheet rows to Go structs with tags\n- **Type Safety**: Automatic type conversion and validation\n- **Rich Querying**: Support for WHERE, LIMIT, OFFSET, and various operators\n- **Insert Operations**: Add new rows to sheets\n- **Idiomatic Go**: Follows Go best practices and conventions\n\n## Installation\n\n```bash\ngo get github.com/jonaylor89/sheetsql\n```\n\n## Quick Start\n\n### Setup\n\n1. Create a Google Cloud project and enable the Google Sheets API\n2. Create service account credentials and download the JSON file\n3. Share your Google Sheet with the service account email\n\n### Basic Usage\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \n    \"github.com/johannes/sheetsql\"\n    \"google.golang.org/api/option\"\n)\n\ntype User struct {\n    ID    int    `sheet:\"ID\"`\n    Name  string `sheet:\"Name\"`\n    Email string `sheet:\"Email\"`\n    Age   int    `sheet:\"Age\"`\n    City  string `sheet:\"City\"`\n}\n\nfunc main() {\n    ctx := context.Background()\n    \n    // Initialize client\n    client, err := sheetsql.NewClient(\n        ctx, \n        \"your-spreadsheet-id\",\n        option.WithCredentialsFile(\"path/to/credentials.json\"),\n    )\n    if err != nil {\n        log.Fatal(err)\n    }\n    \n    // Query all users\n    var users []User\n    err = client.From(\"Users\").Get(\u0026users)\n    if err != nil {\n        log.Fatal(err)\n    }\n    \n    for _, user := range users {\n        fmt.Printf(\"%s (%d) - %s\\n\", user.Name, user.Age, user.City)\n    }\n}\n```\n\n## API Reference\n\n### Fluent API\n\n#### Basic Queries\n\n```go\n// Get all rows\nvar users []User\nerr := client.From(\"Users\").Get(\u0026users)\n\n// With WHERE clause\nerr = client.From(\"Users\").\n    Where(\"Age\", \"\u003e\", 18).\n    Get(\u0026users)\n\n// Multiple WHERE clauses (AND)\nerr = client.From(\"Users\").\n    Where(\"Age\", \"\u003e\", 18).\n    Where(\"City\", \"=\", \"New York\").\n    Get(\u0026users)\n\n// With LIMIT and OFFSET\nerr = client.From(\"Users\").\n    Where(\"Age\", \"\u003e\", 18).\n    Limit(10).\n    Offset(5).\n    Get(\u0026users)\n```\n\n#### Supported Operators\n\n- `=` or `==` - Equal\n- `!=` - Not equal\n- `\u003e` - Greater than\n- `\u003c` - Less than\n- `\u003e=` - Greater than or equal\n- `\u003c=` - Less than or equal\n- `LIKE` - Contains (case-insensitive)\n\n#### Insert Operations\n\n```go\nnewUser := User{\n    Name:  \"John Doe\",\n    Email: \"john@example.com\",\n    Age:   30,\n    City:  \"New York\",\n}\n\nerr := client.From(\"Users\").Insert(newUser)\n```\n\n### SQL API\n\nFor those who prefer SQL syntax:\n\n```go\nparser := sheetsql.NewSQLParser(client)\n\n// Basic SELECT\nvar users []User\nerr := parser.Query(\"SELECT * FROM Users\", \u0026users)\n\n// With WHERE clause\nerr = parser.Query(\"SELECT * FROM Users WHERE Age \u003e 25\", \u0026users)\n\n// Complex queries\nerr = parser.Query(`\n    SELECT * FROM Users \n    WHERE Age \u003e 20 AND City = 'New York' \n    LIMIT 10 OFFSET 5\n`, \u0026users)\n```\n\n#### Supported SQL Features\n\n- `SELECT * FROM table`\n- `WHERE` clauses with AND conditions\n- `LIMIT` and `OFFSET`\n- Operators: `=`, `!=`, `\u003c\u003e`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`, `LIKE`\n- String literals with single or double quotes\n- Automatic type conversion for numbers and booleans\n\n### Struct Tags\n\nUse the `sheet` tag to map struct fields to sheet columns:\n\n```go\ntype User struct {\n    ID       int    `sheet:\"ID\"`\n    FullName string `sheet:\"Name\"`        // Maps to \"Name\" column\n    Email    string `sheet:\"Email\"`\n    Age      int    `sheet:\"Age\"`\n    Location string `sheet:\"City\"`        // Maps to \"City\" column\n}\n```\n\nIf no tag is provided, the struct field name is used as the column name.\n\n### Supported Types\n\n- `string`\n- `int`, `int8`, `int16`, `int32`, `int64`\n- `float32`, `float64`\n- `bool`\n\n## Testing\n\n### Unit Tests\n\n```bash\ngo test ./...\n```\n\n### Integration Tests\n\nSet up environment variables and run integration tests:\n\n```bash\nexport GOOGLE_CREDENTIALS_FILE=/path/to/credentials.json\ngo test -v ./... -run Integration\n```\n\n### Write Tests\n\nTo enable tests that modify the sheet:\n\n```bash\nexport ENABLE_WRITE_TESTS=true\ngo test -v ./... -run Integration\n```\n\n## Examples\n\nRun the example program:\n\n```bash\ncd examples\nexport GOOGLE_CREDENTIALS_FILE=/path/to/credentials.json\ngo run main.go\n```\n\nEnable write examples:\n\n```bash\nexport ENABLE_WRITE_EXAMPLES=true\ngo run main.go\n```\n\n## Sheet Structure Requirements\n\nYour Google Sheet should have:\n\n1. **Header row**: First row contains column names\n2. **Data rows**: Subsequent rows contain data\n3. **Consistent columns**: All rows should have the same number of columns\n\nExample sheet structure:\n```\n| ID | Name      | Email           | Age | City      |\n|----|-----------|-----------------|-----|-----------|\n| 1  | John Doe  | john@email.com  | 30  | New York  |\n| 2  | Jane Smith| jane@email.com  | 25  | Boston    |\n```\n\n## Authentication\n\n### Service Account (Recommended)\n\n1. Create a service account in Google Cloud Console\n2. Download the JSON credentials file\n3. Share your sheet with the service account email\n\n```go\nclient, err := sheetsql.NewClient(\n    ctx, \n    spreadsheetID,\n    option.WithCredentialsFile(\"credentials.json\"),\n)\n```\n\n### Other Authentication Methods\n\n```go\n// With credentials JSON directly\nclient, err := sheetsql.NewClient(\n    ctx,\n    spreadsheetID,\n    option.WithCredentialsJSON([]byte(credentialsJSON)),\n)\n\n// With API key (read-only, public sheets)\nclient, err := sheetsql.NewClient(\n    ctx,\n    spreadsheetID,\n    option.WithAPIKey(\"your-api-key\"),\n)\n```\n\n## Error Handling\n\nThe library returns detailed errors for common issues:\n\n```go\nvar users []User\nerr := client.From(\"NonExistentSheet\").Get(\u0026users)\nif err != nil {\n    log.Printf(\"Query failed: %v\", err)\n}\n```\n\n## Performance Considerations\n\n- **Batch Operations**: The library fetches entire sheets and filters in memory\n- **Caching**: Consider caching results for frequently accessed data\n- **Sheet Size**: Performance decreases with very large sheets (\u003e10k rows)\n- **API Limits**: Google Sheets API has rate limits and quotas\n\n## Limitations\n\n- **Read-heavy**: Optimized for read operations\n- **No Transactions**: No support for atomic operations\n- **No Joins**: Cannot join data across multiple sheets\n- **No Aggregations**: No built-in support for SUM, COUNT, etc.\n- **Update/Delete**: Not yet implemented (coming soon)\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure all tests pass\n5. Submit a pull request\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Roadmap\n\n- [ ] Batch insert operations\n- [ ] Aggregation functions\n- [ ] Multiple sheet joins\n- [ ] Caching layer\n- [ ] Connection pooling\n- [ ] Schema validation\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonaylor89%2Fsheetsql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonaylor89%2Fsheetsql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonaylor89%2Fsheetsql/lists"}