{"id":19495119,"url":"https://github.com/wttj/postgres-sigil","last_synced_at":"2025-12-12T00:13:11.373Z","repository":{"id":50346905,"uuid":"517643636","full_name":"WTTJ/postgres-sigil","owner":"WTTJ","description":"A sigil to make it easier to safely write Postgres queries in Elixir","archived":false,"fork":false,"pushed_at":"2022-08-03T08:17:40.000Z","size":49,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-04T03:41:11.824Z","etag":null,"topics":["ecto","elixir","postgresql"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/postgres_sigil","language":"Elixir","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/WTTJ.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}},"created_at":"2022-07-25T11:49:23.000Z","updated_at":"2024-01-29T10:24:08.000Z","dependencies_parsed_at":"2022-09-06T07:51:35.941Z","dependency_job_id":null,"html_url":"https://github.com/WTTJ/postgres-sigil","commit_stats":null,"previous_names":["ottatech/postgres-sigil"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WTTJ%2Fpostgres-sigil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WTTJ%2Fpostgres-sigil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WTTJ%2Fpostgres-sigil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WTTJ%2Fpostgres-sigil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WTTJ","download_url":"https://codeload.github.com/WTTJ/postgres-sigil/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250900189,"owners_count":21505003,"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":["ecto","elixir","postgresql"],"created_at":"2024-11-10T21:36:05.910Z","updated_at":"2025-12-12T00:13:11.342Z","avatar_url":"https://github.com/WTTJ.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Postgres Sigil\n\n![CI build](https://github.com/ottatech/postgres-sigil/actions/workflows/config.yml/badge.svg)\n[![Hex.pm Version](https://img.shields.io/hexpm/v/postgres_sigil.svg?style=flat)](https://hex.pm/packages/postgres_sigil)\n[![Hexdocs.pm](https://img.shields.io/static/v1?style=flat\u0026label=hexdocs\u0026message=postgres_sigil\u0026color=blueviolet)](https://hexdocs.pm/postgres_sigil)\n\nA library to improve the ergonomics of working with [Postgrex](https://github.com/elixir-ecto/postgrex).\nIt can be thought of as a middle ground between [Ecto](https://github.com/elixir-ecto/ecto) and \n[ayesql](https://github.com/alexdesousa/ayesql) in that the goal is to write queries in plain SQL \nbut within Elixir source files, not separately. The syntax is heavily inspired by the Scala library [doobie](https://tpolecat.github.io/doobie/).\n\n## Writing queries\n\n### Basic selects\n\nUse the `~q` sigil to construct queries. Variables can be safely interpolated into the query\nand will be replaced with `$1`, `$2` etc positional parameters before being sent to Postgres.\n\n```elixir\n~q\"SELECT * FROM users WHERE id = #{id}\" |\u003e to_tuple()\n# result: {\"SELECT * FROM users WHERE id = $1\", [1245]}\n```\n\n### Fragments\n\nQueries can be interpolated into other queries which allows you to re-use fragments.\n\n```elixir\nrecently_seen = ~q\"last_seen \u003e= NOW() - INTERVAL '1 day'\"\n~q\"SELECT * FROM users WHERE #{recently_seen}\" |\u003e to_tuple()\n# result: {\"SELECT * FROM users WHERE last_seen \u003e= NOW() - INTERVAL '1 day'\", []}\n```\n\n### Inserts and updates\n\nInterpolating a call to `values()` will result in the value being enclosed in brackets\nand prefixed with `VALUES`.\n\nNote you cannot directly insert maps because they do not have a defined order.\n\n```elixir\nuser = %{name: \"Tom\", email: \"tom@example.com\"}\n~q\"INSERT INTO users (name, email) #{values(user.name, user.email)}\" |\u003e to_tuple()\n# result: {\"INSERT INTO users (name, email) VALUES ($1, $2)\", [\"Tom\", \"tom@example.com\"]}\n```\n\nThe main benefit this syntax offers is that if you pass a list to `values` it'll generate\nthe correct SQL for a batch insert operation:\n\n```elixir\n~q\"INSERT INTO users (name, email, address1) #{values([\n  {\"A\", \"a@a.com\", \"123 fake street\"},\n  {\"B\", \"b@b.com\", \"234 fake street\"}\n])}\" |\u003e to_tuple()\n\n# result: {\n#  \"INSERT INTO users (name, email, address1) VALUES ($1, $2, $3), ($4, $5, $6)\",\n#  [\"A\", \"a@a.com\", \"123 fake street\", \"B\", \"b@b.com\", \"234 fake street\"]\n#}\n```\n\n### Dynamic columns\n\nColumn names can be interpolated by wrapping the interpolation in `col()`\n\n```elixir\n~q\"SELECT #{col(\"name\")} FROM users\" |\u003e to_tuple()\n# result: {\"SELECT \\\"name\\\" FROM users\", []}\n```\n\n### Unsafe interpolation\n\nIf you're really up to no good then you can wrap interpolations in `unsafe()` which\nwill result in the value being directly placed into the query with no escaping.\nThis should only be used if you're fully aware of the [security implications](https://owasp.org/www-community/attacks/SQL_Injection).\n\n```elixir\n~q\"SELECT #{unsafe(\"name\")} FROM users\"\n# result: {\"SELECT name FROM users\", []}\n```\n\n## Running queries\n\nYou can run the queries either with Ecto or directly with Postgrex.\n\n```elixir\n~q\"SELECT * FROM users\" |\u003e PostgresSigil.Ecto.query!(MyApp.Repo) # ecto\n~q\"SELECT * FROM users\" |\u003e PostgresSigil.Postgrex.query!(:pid) # postgrex\n```\n\n## Explaining queries\n\nBoth the Ecto and Postgrex integrations provide `explain_to_file!` that will\nrun the query with `EXPLAIN ANALYZE` and write the result to a file named `explain.json`.\n\nThis can then be pasted into https://explain.dalibo.com/ for analysis.\n\n## Handling results\n\n`PostgresSigil.Results` defines a number of functions to make it easier to process the results that Postgrex returns.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwttj%2Fpostgres-sigil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwttj%2Fpostgres-sigil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwttj%2Fpostgres-sigil/lists"}