{"id":17694977,"url":"https://github.com/asg017/sqlite-ulid","last_synced_at":"2025-04-07T11:08:11.334Z","repository":{"id":65470851,"uuid":"580533978","full_name":"asg017/sqlite-ulid","owner":"asg017","description":"A SQLite extension for generating and working with ULIDs","archived":false,"fork":false,"pushed_at":"2023-10-06T22:57:31.000Z","size":217,"stargazers_count":117,"open_issues_count":4,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-05-29T20:42:14.253Z","etag":null,"topics":["sqlite","sqlite-extension"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asg017.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","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}},"created_at":"2022-12-20T19:58:44.000Z","updated_at":"2024-06-20T00:09:20.171Z","dependencies_parsed_at":"2024-06-20T00:09:19.422Z","dependency_job_id":"2355cedf-6c58-4828-8cd9-bb097ccd4ae7","html_url":"https://github.com/asg017/sqlite-ulid","commit_stats":{"total_commits":174,"total_committers":2,"mean_commits":87.0,"dds":0.005747126436781658,"last_synced_commit":"942d62ca1ebc483df3cc8d31af71cfff4778ed7f"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asg017%2Fsqlite-ulid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asg017%2Fsqlite-ulid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asg017%2Fsqlite-ulid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asg017%2Fsqlite-ulid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asg017","download_url":"https://codeload.github.com/asg017/sqlite-ulid/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247640464,"owners_count":20971557,"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":["sqlite","sqlite-extension"],"created_at":"2024-10-24T13:50:42.342Z","updated_at":"2025-04-07T11:08:11.307Z","avatar_url":"https://github.com/asg017.png","language":"Python","readme":"# sqlite-ulid\n\nA SQLite extension for generating and working with [ULIDs](https://github.com/ulid/spec). Built on top of [sqlite-loadable-rs](https://github.com/asg017/sqlite-loadable-rs) and [ulid-rs](https://github.com/dylanhart/ulid-rs).\n\nIf your company or organization finds this library useful, consider [supporting my work](#supporting)!\n\n## Usage\n\n```sql\n.load ./ulid0\n\nselect ulid(); -- '01gqr4j69cc7w1xdbarkcbpq17'\nselect ulid_bytes(); -- X'0185310899dd7662b8f1e5adf9a5e7c0'\nselect ulid_with_prefix('invoice'); -- 'invoice_01gqr4jmhxhc92x1kqkpxb8j16'\nselect ulid_with_datetime('2023-01-26 22:53:20.556); -- '01gqr4j69cc7w1xdbarkcbpq17'\nselect ulid_datetime('01gqr4j69cc7w1xdbarkcbpq17') -- '2023-01-26 22:53:20.556'\n```\n\nUse as a `PRIMARY KEY` for a table.\n\n```sql\ncreate table log_events(\n  id ulid primary key,\n  data any\n);\n\n\ninsert into log_events(id, data) values (ulid(), 1);\ninsert into log_events(id, data) values (ulid(), 2);\ninsert into log_events(id, data) values (ulid(), 3);\n\nselect * from log_events;\n/*\n┌────────────────────────────┬──────┐\n│             id             │ data │\n├────────────────────────────┼──────┤\n│ 01gqr4vr487bytsf10ktfmheg4 │ 1    │\n│ 01gqr4vr4dfcfk80m2yp6j866z │ 2    │\n│ 01gqr4vrjxg0yex9jr0f100v1c │ 3    │\n└────────────────────────────┴──────┘\n*/\n```\n\nConsider using [`ulid_bytes()`](./docs.md#ulid_bytes) for speed and smaller IDs. They generate about 1.6x faster than `ulid()`, and take up 16 bytes instead of 26 bytes. You can use `ulid()` to create a text representation of a BLOB ULID.\n\n```sql\n\ncreate table log_events(\n  id ulid primary key,\n  data any\n);\n\n\ninsert into log_events(id, data) values (ulid_bytes(), 1);\ninsert into log_events(id, data) values (ulid_bytes(), 2);\ninsert into log_events(id, data) values (ulid_bytes(), 3);\n\nselect hex(id), ulid(id), data from log_events;\n/*\n┌──────────────────────────────────┬────────────────────────────┬──────┐\n│             hex(id)              │          ulid(id)          │ data │\n├──────────────────────────────────┼────────────────────────────┼──────┤\n│ 0185F0539EBF286DA9F56BA4D9981783 │ 01gqr577nz51ptkxbbmkcsg5w3 │ 1    │\n│ 0185F0539EC54F85745C1ECB64DF3A97 │ 01gqr577p59y2q8q0ysdjdyemq │ 2    │\n│ 0185F0539ED48113F6F67BF3F6A4BFF7 │ 01gqr577pmg49zdxkvyfva9fzq │ 3    │\n└──────────────────────────────────┴────────────────────────────┴──────┘\n*/\n```\n\nExtract the timestamp component of a ULID with [`ulid_datetime()`](./docs.md#ulid_datetime).\n\n```sql\nselect ulid_datetime(ulid()); -- '2023-01-26 23:07:36.508'\nselect unixepoch(ulid_datetime(ulid())); -- 1674774499\nselect strftime('%Y-%m-%d', ulid_datetime(ulid())); -- '2023-01-26''\n```\n\nConsider using [`ulid_with_prefix()`](./docs.md#ulid_with_prefix) to generate a text ULID with a given prefix, to differentiate between different ID types.\n\n```sql\nselect ulid_with_prefix('customer'); -- 'customer_01gqr5j1ebk31wv30wgp8ebehj'\nselect ulid_with_prefix('product'); -- 'product_01gqr5prjgsa77dhrxf2dt1dgv'\nselect ulid_with_prefix('order'); -- 'order_01gqr5q35n68jk0sycy1ntr083'\n\n\n```\n\n## Quick benchmarks\n\nNot definitive, hastily ran on a Macbook, not representative of real-life usecases. The `uuid()` SQL function comes from the [official `uuid.c` extension](https://sqlite.org/src/file/ext/misc/uuid.c).\n\n| Test case                                      | Time                                            |\n| ---------------------------------------------- | ----------------------------------------------- |\n| `generate_series()` to generate 1 million rows | `28.5 ms ±   0.8 ms` (`1x`)                     |\n| Calling `ulid_bytes()` 1 million times         | `88.4 ms ±   2.8 ms`,, `3.10 ± 0.13` slower     |\n| Calling `uuid()` 1 million times               | `141.6 ms ±   1.5 ms`, or `4.97 ± 0.15` slower  |\n| Calling `ulid()` 1 million times               | `344.3 ms ±  11.9 ms`, or `12.07 ± 0.53` slower |\n\nSo `ulid_bytes()` is pretty fast, but returns an unreadable blob instead of a nicely formatted text ID. The `ulid()` function does that, but is more than twice as slow than `uuid()`.\n\nHowever, generating 1 million `ulid()` IDs in ~350ms is most likely \"good enough\" for most SQLite usecases.\n\n## Using with...\n\n| Language       | Install                                                      |                                                                                                                                                                                             |\n| -------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Python         | `pip install sqlite-ulid`                                    | [![PyPI](https://img.shields.io/pypi/v/sqlite-ulid.svg?color=blue\u0026logo=python\u0026logoColor=white)](https://pypi.org/project/sqlite-ulid/)                                                      |\n| Datasette      | `datasette install datasette-sqlite-ulid`                    | [![Datasette](https://img.shields.io/pypi/v/datasette-sqlite-ulid.svg?color=B6B6D9\u0026label=Datasette+plugin\u0026logoColor=white\u0026logo=python)](https://datasette.io/plugins/datasette-sqlite-ulid) |\n| Node.js        | `npm install sqlite-ulid`                                    | [![npm](https://img.shields.io/npm/v/sqlite-ulid.svg?color=green\u0026logo=nodedotjs\u0026logoColor=white)](https://www.npmjs.com/package/sqlite-ulid)                                                |\n| Deno           | [`deno.land/x/sqlite_ulid`](https://deno.land/x/sqlite_ulid) | [![deno.land/x release](https://img.shields.io/github/v/release/asg017/sqlite-ulid?color=fef8d2\u0026include_prereleases\u0026label=deno.land%2Fx\u0026logo=deno)](https://deno.land/x/sqlite_ulid)        |\n| Ruby           | `gem install sqlite-ulid`                                    | ![Gem](https://img.shields.io/gem/v/sqlite-ulid?color=red\u0026logo=rubygems\u0026logoColor=white)                                                                                                    |\n| Rust           | `cargo add sqlite-ulid`                                      | [![Crates.io](https://img.shields.io/crates/v/sqlite-ulid?logo=rust)](https://crates.io/crates/sqlite-ulid)                                                                                 |\n| Github Release |                                                              | ![GitHub tag (latest SemVer pre-release)](https://img.shields.io/github/v/tag/asg017/sqlite-ulid?color=lightgrey\u0026include_prereleases\u0026label=Github+release\u0026logo=github)                      |\n\n\u003c!--\n| Elixir         | [`hex.pm/packages/sqlite_ulid`](https://hex.pm/packages/sqlite_ulid) | [![Hex.pm](https://img.shields.io/hexpm/v/sqlite_ulid?color=purple\u0026logo=elixir)](https://hex.pm/packages/sqlite_ulid)                                                                       |\n| Go             | `go get -u github.com/asg017/sqlite-ulid/bindings/go`               | [![Go Reference](https://pkg.go.dev/badge/github.com/asg017/sqlite-ulid/bindings/go.svg)](https://pkg.go.dev/github.com/asg017/sqlite-ulid/bindings/go)                                     |\n--\u003e\n\nThe [Releases page](https://github.com/asg017/sqlite-ulid/releases) contains pre-built binaries for Linux x86_64, MacOS, and Windows.\n\n### Python\n\nFor Python developers, install the [`sqlite-ulid` package](https://pypi.org/package/sqlite-ulid/) with:\n\n```\npip install sqlite-ulid\n```\n\n```python\nimport sqlite3\nimport sqlite_ulid\ndb = sqlite3.connect(':memory:')\ndb.enable_load_extension(True)\nsqlite_ulid.load(db)\ndb.execute('select ulid()').fetchone()\n# ('01gr7gwc5aq22ycea6j8kxq4s9',)\n```\n\nSee [`python/sqlite_ulid`](./python/sqlite_ulid/README.md) for more details.\n\n### Node.js\n\nFor Node.js developers, install the [`sqlite-ulid` npm package](https://www.npmjs.com/package/sqlite-ulid) with:\n\n```\nnpm install sqlite-ulid\n```\n\n```js\nimport Database from \"better-sqlite3\";\nimport * as sqlite_ulid from \"sqlite-ulid\";\n\nconst db = new Database(\":memory:\");\ndb.loadExtension(sqlite_ulid.getLoadablePath());\n```\n\nSee [`npm/sqlite-ulid/README.md`](./npm/sqlite-ulid/README.md) for more details.\n\n### Deno\n\nFor [Deno](https://deno.land/) developers, use the [deno.land/x/sqlite_ulid](https://deno.land/x/sqlite_ulid) module:\n\n```ts\nimport { Database } from \"https://deno.land/x/sqlite3@0.8.0/mod.ts\";\nimport * as sqlite_ulid from \"https://deno.land/x/sqlite_ulid@v${VERSION}/mod.ts\";\n\nconst db = new Database(\":memory:\");\n\ndb.enableLoadExtension = true;\nsqlite_ulid.load(db);\n\nconst [version] = db.prepare(\"select ulid_version()\").value\u003c[string]\u003e()!;\n\nconsole.log(version);\n```\n\n### Datasette\n\nAnd for [Datasette](https://datasette.io/), install the [`datasette-sqlite-ulid` plugin](https://datasette.io/plugins/datasette-sqlite-ulid) with:\n\n```\ndatasette install datasette-sqlite-ulid\n```\n\nSee [`python/datasette_sqlite_ulid`](./python/datasette_sqlite_ulid/README.md) for more details.\n\n### As a loadable extension\n\nIf you want to use `sqlite-ulid` as a [Runtime-loadable extension](https://www.sqlite.org/loadext.html), Download the `ulid0.dylib` (for MacOS), `ulid0.so` (Linux), or `ulid0.dll` (Windows) file [from a release](https://github.com/asg017/sqlite-ulid/releases) and load it into your SQLite environment.\n\n\u003e **Note:**\n\u003e The `0` in the filename (`ulid0.dylib`/ `ulid0.so`/`ulid0.dll`) denotes the major version of `sqlite-ulid`. Currently `sqlite-ulid` is pre v1, so expect breaking changes in future versions.\n\nFor example, if you are using the [SQLite CLI](https://www.sqlite.org/cli.html), you can load the library like so:\n\n```sql\n.load ./ulid0\nselect ulid_version();\n-- v0.1.0\n```\n\nIn Python, you should prefer the [`sqlite-ulid` Python package](./python/sqlite_ulid/README.md). However, you can manually load a pre-compiled extension with the builtin [sqlite3 module](https://docs.python.org/3/library/sqlite3.html):\n\n```python\nimport sqlite3\ncon = sqlite3.connect(\":memory:\")\ncon.enable_load_extension(True)\ncon.load_extension(\"./ulid0\")\nprint(con.execute(\"select ulid_version()\").fetchone())\n# ('v0.1.0',)\n```\n\nOr in Node.js using [better-sqlite3](https://github.com/WiseLibs/better-sqlite3):\n\n```javascript\nconst Database = require(\"better-sqlite3\");\nconst db = new Database(\":memory:\");\ndb.loadExtension(\"./ulid0\");\nconsole.log(db.prepare(\"select ulid_version()\").get());\n// { 'ulid_version()': 'v0.1.0' }\n```\n\nWith [Datasette](https://datasette.io/), you should prefer the [`datasette-sqlite-ulid` Datasette plugin](./python/datasette_sqlite_ulid/README.md). However, you can manually load a pre-compiled extension into a Datasette instance like so:\n\n```\ndatasette data.db --load-extension ./ulid0\n```\n\n## Supporting\n\nI (Alex 👋🏼) spent a lot of time and energy on this project and [many other open source projects](https://github.com/asg017?tab=repositories\u0026q=\u0026type=\u0026language=\u0026sort=stargazers). If your company or organization uses this library (or you're feeling generous), then please [consider supporting my work](https://alexgarcia.ulid/work.html), or share this project with a friend!\n\n## See also\n\n- [sqlite-xsv](https://github.com/asg017/sqlite-xsv), A SQLite extension for working with CSVs\n- [sqlite-loadable](https://github.com/asg017/sqlite-loadable-rs), A framework for writing SQLite extensions in Rust\n- [sqlite-http](https://github.com/asg017/sqlite-http), A SQLite extension for making HTTP requests\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasg017%2Fsqlite-ulid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasg017%2Fsqlite-ulid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasg017%2Fsqlite-ulid/lists"}