{"id":17967186,"url":"https://github.com/alifiroozi80/duckdb","last_synced_at":"2025-06-14T07:36:45.781Z","repository":{"id":259850357,"uuid":"879219149","full_name":"alifiroozi80/duckdb","owner":"alifiroozi80","description":"GORM duckdb driver","archived":false,"fork":false,"pushed_at":"2025-04-12T13:08:00.000Z","size":72,"stargazers_count":12,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T13:37:52.468Z","etag":null,"topics":["duckdb","go","gorm"],"latest_commit_sha":null,"homepage":"","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/alifiroozi80.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2024-10-27T10:33:38.000Z","updated_at":"2025-04-12T13:06:08.000Z","dependencies_parsed_at":"2024-11-30T07:31:03.123Z","dependency_job_id":"269f55e4-286e-44a0-9fea-ca367ad64026","html_url":"https://github.com/alifiroozi80/duckdb","commit_stats":{"total_commits":21,"total_committers":2,"mean_commits":10.5,"dds":0.09523809523809523,"last_synced_commit":"8a1b3866401c93f0ee9b2a6cf3c37dd42e876d80"},"previous_names":["alifiroozi80/duckdb"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/alifiroozi80/duckdb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alifiroozi80%2Fduckdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alifiroozi80%2Fduckdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alifiroozi80%2Fduckdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alifiroozi80%2Fduckdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alifiroozi80","download_url":"https://codeload.github.com/alifiroozi80/duckdb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alifiroozi80%2Fduckdb/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259777195,"owners_count":22909617,"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","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":["duckdb","go","gorm"],"created_at":"2024-10-29T14:04:28.673Z","updated_at":"2025-06-14T07:36:45.769Z","avatar_url":"https://github.com/alifiroozi80.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/duckdb/duckdb/main/logo/DuckDB_Logo-horizontal-dark-mode.svg\"\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/duckdb/duckdb/main/logo/DuckDB_Logo-horizontal-dark-mode.svg\"\u003e\n    \u003cimg alt=\"DuckDB logo\" src=\"https://raw.githubusercontent.com/duckdb/duckdb/main/logo/DuckDB_Logo-horizontal-dark-mode.svg\" height=\"100\"\u003e\n  \u003c/picture\u003e\n\n  \u003ch3 align=\"center\"\u003eGORM DuckDB Driver\u003c/h3\u003e\n\n  \u003cdiv style=\"display: flex; justify-content: center; gap: 10px; flex-wrap: wrap;\"\u003e\n    \u003ca href=\"https://pkg.go.dev/github.com/alifiroozi80/duckdb\" style=\"text-decoration: none;\"\u003e\n      \u003cimg src=\"https://pkg.go.dev/badge/github.com/alifiroozi80/duckdb.svg\" alt=\"Go Reference\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://img.shields.io/github/go-mod/go-version/alifiroozi80/duckdb?logo=go\" style=\"text-decoration: none;\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/go-mod/go-version/alifiroozi80/duckdb?logo=go\" alt=\"Go version\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://img.shields.io/github/v/release/alifiroozi80/duckdb\" style=\"text-decoration: none;\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/v/release/alifiroozi80/duckdb\" alt=\"GitHub release\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://goreportcard.com/report/github.com/alifiroozi80/duckdb\" style=\"text-decoration: none;\"\u003e\n      \u003cimg src=\"https://goreportcard.com/badge/github.com/alifiroozi80/duckdb\" alt=\"Go Report Card\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://img.shields.io/github/license/alifiroozi80/duckdb?\u0026color=blue\" style=\"text-decoration: none;\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/license/alifiroozi80/duckdb?\u0026color=blue\" alt=\"License\"\u003e\n    \u003c/a\u003e\n  \u003c/div\u003e\n\n  \u003cp align=\"center\" style=\"margin-top: 20px;\"\u003e\n    \u003ca href=\"https://github.com/alifiroozi80/duckdb/issues\" style=\"text-decoration: none;\"\u003eReport Bug\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\n---\n\n## Quick Start\n\n```go\nimport (\n  \"github.com/alifiroozi80/duckdb\"\n  \"gorm.io/gorm\"\n)\n\n// DO NOT use 'gorm.Model' here. See 'Limitations' for more.\ntype Product struct {\n\tID        uint `gorm:\"primarykey\"`\n\tCode      string\n\tPrice     uint\n\tCreatedAt time.Time\n\tUpdatedAt time.Time\n}\n\nfunc main() {\n\t// duckdb extentions: .ddb, .duckdb, .db\n\tdb, err := gorm.Open(duckdb.Open(\"duckdb.ddb\"), \u0026gorm.Config{})\n\tif err != nil {\n\t\tpanic(\"failed to connect database\")\n\t}\n\n\t// Migrate the schema\n\terr = db.AutoMigrate(\u0026Product{})\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\t// Create\n\tdb.Create(\u0026Product{Code: \"D42\", Price: 100})\n\n        // Read\n\tvar product Product\n\tdb.First(\u0026product, 1)                 // find product with integer primary key\n\tdb.First(\u0026product, \"code = ?\", \"D42\") // find product with code D42\n\n\t// Update - update product's price to 200\n\tdb.Model(\u0026product).Update(\"Price\", 200)\n\t// Update - update multiple fields\n\tdb.Model(\u0026product).Updates(Product{Price: 200, Code: \"F42\"}) // non-zero fields\n\tdb.Model(\u0026product).Updates(map[string]interface{}{\"Price\": 200, \"Code\": \"F42\"})\n\n\t// Delete - delete product\n\tdb.Delete(\u0026product, 1)\n}\n```\n\nCheckout [https://gorm.io](https://gorm.io) for details.\n\n\n## Limitations\n\n#### `deleted_at` field.\n\nDuckDB has two index types:\n\n- Min-Max (Zonemap)\n- [Adaptive Radix Tree](https://db.in.tum.de/~leis/papers/ART.pdf)\nIn DuckDB, ART indexes are automatically created for columns with a `UNIQUE` or `PRIMARY KEY` constraint and can be defined using `CREATE INDEX`.\n\nHowever, every technology has its pros and cons. Despite being helpful (read attached pdf), ART indexes have some limitations.\n\nART indexes create a secondary copy of the data in a second location – this complicates processing, particularly when combined with transactions. Certain limitations apply when it comes to modifying data stored in secondary indexes.\n\nDue to the presence of transactions, data can only be removed from the index after the transaction that performed the delete is committed and no further transactions that refer to the old entry are still present in the index. As a result, transactions that perform deletions followed by insertions may trigger unexpected, unique constraint violations, as the deleted tuple has not yet been removed from the index. For example:\n\nGORM will update the `deleted_at` column when you perform a `db.Delete()`. so your `db.Delete()` will be translate to:\n\n```sql\nUPDATE products SET deleted_at='2024-11-01 12:06:00.942' WHERE products.id = 1 AND products.deleted_at IS NULL;\n```\n\nAnd it cause an error:\n\n```bash\nConstraint Error: Duplicate key \"id: 1\" violates primary key constraint. If this is an unexpected constraint violation please double check with the known index limitations section in our documentation (https://duckdb.org/docs/sql/indexes).\n```\n\nThat is why you should not use the default `gorm.Model` structure and manually use `ID`, `CreatedAt` and `UpdatedAt`.\n\nFor more info, see [DuckDB documentations](https://duckdb.org/docs/sql/constraints#primary-key-and-unique-constraint).\n\n---\n\n#### JSONB\n\nDuckDB doesn't support JSONB schema yet, so whenever you use `gorm:\"type:jsonb\"`, it will translate it to `gorm:\"type:json\"` under the hood.\n\nWhy did I add this?\n\nBecause in a couple of projects that I was contributing to, this type was being used in GORM drivers, so I added this small thing to avoid facing the below error:\n\n```bash\nCatalogue Error: Type with name jsonb does not exist!\n```\n\n\u003c!-- CONTRIBUTING --\u003e\n\n## Contributing\n\nAny contributions you make are **greatly appreciated**.\n\nSee [here](https://github.com/alifiroozi80/duckdb/blob/main/CONTRIBUTING.md) for more details on contributing.\n\n### Roadmap\n\n- [ ] Support switch indexes between ART and Min-Max in the configuraion.\n- [ ] Implement TODO functions:\n\t- ColumnTypes\n\t- CreateConstraint\n- [ ] Support `sequence` for each field that needs auto-increment (See [here](https://github.com/alifiroozi80/duckdb/issues/1)).\n\n\u003c!-- LICENSE --\u003e\n\n## License\n\nThe license is under the MIT License. See [LICENSE](https://github.com/alifiroozi80/duckdb/blob/main/LICENSE) for more\ninformation.\n\n## ❤ Show your support\n\nGive a ⭐️ if this project helped you!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falifiroozi80%2Fduckdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falifiroozi80%2Fduckdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falifiroozi80%2Fduckdb/lists"}