{"id":20425442,"url":"https://github.com/tophat/ormar-postgres-extensions","last_synced_at":"2025-04-24T00:23:45.914Z","repository":{"id":43829286,"uuid":"392044162","full_name":"tophat/ormar-postgres-extensions","owner":"tophat","description":"Extensions to the Ormar ORM to support PostgreSQL specific types","archived":false,"fork":false,"pushed_at":"2024-08-25T05:56:50.000Z","size":84,"stargazers_count":22,"open_issues_count":11,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-09-25T16:54:15.376Z","etag":null,"topics":["hacktoberfest","ormar","postgresql"],"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/tophat.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2021-08-02T17:52:07.000Z","updated_at":"2024-07-20T12:17:54.000Z","dependencies_parsed_at":"2024-06-07T00:33:39.479Z","dependency_job_id":"518074e3-20e8-47dc-bdbc-5887d1fe8bd8","html_url":"https://github.com/tophat/ormar-postgres-extensions","commit_stats":{"total_commits":53,"total_committers":7,"mean_commits":7.571428571428571,"dds":0.4339622641509434,"last_synced_commit":"ef2af5834067c67cf7aebe2e6a7fb7f2e3e888fc"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":"tophat/new-project-kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tophat%2Formar-postgres-extensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tophat%2Formar-postgres-extensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tophat%2Formar-postgres-extensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tophat%2Formar-postgres-extensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tophat","download_url":"https://codeload.github.com/tophat/ormar-postgres-extensions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250536483,"owners_count":21446743,"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":["hacktoberfest","ormar","postgresql"],"created_at":"2024-11-15T07:13:21.452Z","updated_at":"2025-04-24T00:23:45.738Z","avatar_url":"https://github.com/tophat.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ormar-postgres-extensions\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n[![Maturity badge - level 1](https://img.shields.io/badge/Maturity-Level%201%20--%20New%20Project-yellow.svg)](https://github.com/tophat/getting-started/blob/master/scorecard.md) [![Stage](https://img.shields.io/pypi/status/ormar-postgres-extensions)](https://pypi.org/project/ormar-postgres-extensions/) [![Discord](https://img.shields.io/discord/809577721751142410?label=community%20chat)](https://discord.gg/YhK3GFcZrk)\n\n[![Pypi](https://img.shields.io/pypi/v/ormar-postgres-extensions)](https://pypi.org/project/ormar-postgres-extensions/) [![Wheel](https://img.shields.io/pypi/wheel/ormar-postgres-extensions)](https://pypi.org/project/ormar-postgres-extensions/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ormar-postgres-extensions) [![PyPI - Downloads](https://img.shields.io/pypi/dm/ormar-postgres-extensions)](https://pypi.org/project/ormar-postgres-extensions/) [![PyPI - License](https://img.shields.io/pypi/l/ormar-postgres-extensions)](./LICENSE)\n\n![Build Status](https://github.com/tophat/ormar-postgres-extensions/workflows/Ormar%20Postgres%20Extensions%20CICD/badge.svg) [![codecov](https://codecov.io/gh/tophat/ormar-postgres-extensions/branch/main/graph/badge.svg)](https://codecov.io/gh/tophat/ormar-postgres-extensions)\n\n## Overview\n\normar-postgres-extensions is a an extension to the[Ormar](https://github.com/collerek/ormar) ORM. It enables developers to write models that map to native PostgreSQL types.\n\n## Motivation\n\n[Ormar](https://github.com/collerek/ormar) is an amazing async ORM that works with [FastAPI](https://github.com/tiangolo/fastapi). However, it is agnostic to the underlying database used meaning that we cannot use native PostgreSQL types such as UUID or JSONB columns. The aim of this library is to provide Ormar fields that can be used to generate database columns with native PG types.\n\n## Installation\n\n```shell\npython -m pip install ormar-postgres-extensions\n```\n\n## Usage\n\n### Fields\n\nThree native PG fields are provided. The `JSONB` and `UUID` types map to native `JSONB` and `UUID` data types respectively. The `Array` type can be used to create an array column. Using these in an Ormar model is as simple as importing the fields and using them in the model.\n\n#### UUID\n\n```python\nfrom uuid import UUID\n\nimport ormar\nimport ormar_postgres_extensions as ormar_pg_ext\n\n\nclass MyModel(ormar.Model):\n    uuid: UUID = ormar_pg_ext.UUID(unique=True, nullable=False)\n```\n#### JSONB\n```python\nimport ormar\nimport ormar_postgres_extensions as ormar_pg_ext\n\nclass JSONBTestModel(ormar.Model):\n    id: int = ormar.Integer(primary_key=True)\n    data: dict = ormar_pg_ext.JSONB()\n```\n\n##### jsonb_contained_by\n\nThe maps to the [`contains`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.JSONB.Comparator.contained_by) operator in Postgres.\n\n```python\nawait JSONBTestModel.objects.filter(data__jsonb_contained_by=dict(key=\"value\")).all()\n```\n\n##### jsonb_contains\n\nThe maps to the [`contains`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.JSONB.Comparator.contains) operator in Postgres.\n\n```python\nawait JSONBTestModel.objects.filter(data__jsonb_contains=dict(key=\"value\")).all()\n```\n\n##### jsonb_has_all\n\nThe maps to the [`has_all`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.JSONB.Comparator.has_all) operator in Postgres.\n\n```python\nfrom sqlalchemy.dialects.postgresql import array\n\nawait JSONBTestModel.objects.filter(data__jsonb_has_all=array([\"key1\", \"key2\"])).all()\n```\n\n##### jsonb_has_any\n\nThe maps to the [`has_any`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.JSONB.Comparator.has_any) operator in Postgres.\n\n```python\nfrom sqlalchemy.dialects.postgresql import array\n\nawait JSONBTestModel.objects.filter(data__jsonb_has_any=array([\"key1\", \"key2\"])).all()\n```\n\n##### jsonb_has_key\n\nThe maps to the [`has_key`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.JSONB.Comparator.has_key) operator in Postgres.\n\n```python\nawait JSONBTestModel.objects.filter(data__jsonb_has_key=\"key1\").all()\n```\n\n#### Array\n\nArray field requires a bit more setup to pass the type of the array into the field\n\n```python\nimport ormar\nimport sqlalchemy\nimport ormar_postgres_extensions as ormar_pg_ext\n\nclass ModelWithArray(ormar.Model):\n    class Meta:\n        database = database\n        metadata = metadata\n\n    id: int = ormar.Integer(primary_key=True)\n    data: list = ormar_pg_ext.ARRAY(item_type=sqlalchemy.String())\n```\n\nArrays have access to three special methods that map to specific PostgreSQL array functions\n\n##### array_contained_by\n\nThe maps to the [`contained_by`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.ARRAY.Comparator.contained_by) operator in Postgres.\n\n```python\nawait ModelWithArray.objects.filter(data__array_contained_by=[\"a\"]).all()\n```\n\n##### array_contains\n\nThe maps to the [`contains`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.ARRAY.Comparator.contains) operator in Postgres.\n\n```python\nawait ModelWithArray.objects.filter(data__array_contains=[\"a\"]).all()\n```\n\n##### array_overlap\n\nThe maps to the [`overlap`](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#sqlalchemy.dialects.postgresql.ARRAY.Comparator.overlap) operator in Postgres.\n\n```python\nawait ModelWithArray.objects.filter(data__array_overlap=[\"a\"]).all()\n```\n\n\n#### INET / CIDR\n\n```python\nfrom ipaddress import IPv4Address, IPv6Address, IPv4Interface, IPv6Interface\nfrom typing import Union\n\nimport ormar\nimport ormar_postgres_extensions as ormar_pg_ext\n\nIPAddress = Union[\n    IPv4Address,\n    IPv4Interface,\n    IPv6Address,\n    IPv6Interface,\n]\n\nclass INETTestModel(ormar.Model):\n    id: int = ormar.Integer(primary_key=True)\n    inet: IPAddress = ormar_pg_ext.INET()\n    cidr: IPAddress = ormar_pg_ext.CIDR()\n```\n\n##### contained_by\n\nThis maps to the [`\u003c\u003c` operator](https://www.postgresql.org/docs/current/functions-net.html)\n\n```python\nfrom ipaddress import ip_interface\nawait INETTestModel.objects.filter(inet__contained_by=ip_interface(\"192.168.1.0/24\")).all()\n```\n\n##### contained_by_eq\n\nThis maps to the [`\u003c\u003c=` operator](https://www.postgresql.org/docs/current/functions-net.html)\n\n```python\nfrom ipaddress import ip_interface\nawait INETTestModel.objects.filter(inet__contained_by_eq=ip_interface(\"192.168.1.0/24\")).all()\n```\n\n##### contains_subnet\n\nThis maps to the [`\u003e\u003e` operator](https://www.postgresql.org/docs/current/functions-net.html)\n\n```python\nfrom ipaddress import ip_interface\nawait INETTestModel.objects.filter(inet__contains_subnet=ip_interface(\"192.168.1.0/24\")).all()\n```\n\n##### contains_subnet_eq\n\nThis maps to the [`\u003e\u003e=` operator](https://www.postgresql.org/docs/current/functions-net.html)\n\n```python\nfrom ipaddress import ip_interface\nawait INETTestModel.objects.filter(inet__contains_subnet_eq=ip_interface(\"192.168.1.0/24\")).all()\n```\n\n##### contains_or_eq\n\nThis maps to the [`\u0026\u0026` operator](https://www.postgresql.org/docs/current/functions-net.html)\n\n```python\nfrom ipaddress import ip_interface\nawait INETTestModel.objects.filter(inet__contains_or_eq=ip_interface(\"192.168.1.0/24\")).all()\n```\n\n#### MACADDR\n\n```python\nfrom ipaddress import IPv4Address, IPv6Address, IPv4Interface, IPv6Interface\nfrom typing import Union\n\nimport ormar\nimport ormar_postgres_extensions as ormar_pg_ext\n\nclass MacAddrTestModel(ormar.Model):\n    id: int = ormar.Integer(primary_key=True)\n    addr: str = ormar_pg_ext.MACADDR()\n```\n\n## Uninstalling\n\n```python\npip uninstall ormar-postgres-extensions\n```\n\n## Contributing\n\nFeel free to open a PR or GitHub issue. Contributions welcome!\n\nTo develop locally, clone this repository and run `. script/bootstrap` to install test dependencies. You can then use `invoke --list` to see available commands.\nTo run the tests locally, PostgreSQL needs to be running. This can be easily started via `inv database`.\n\n### See contributing [guide](https://github.com/tophat/ormar-postgres-extensions/tree/main/CONTRIBUTING.md)\n## Contributors\n\n_You don't really have to add this section yourself! Simply use [all-contributors](https://allcontributors.org/) by adding comments in your PRs like so:_\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://everttimberg.io\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/6757853?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eEvert Timberg\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#ideas-etimberg\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"#infra-etimberg\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e \u003ca href=\"#maintenance-etimberg\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e \u003ca href=\"https://github.com/tophat/ormar-postgres-extensions/commits?author=etimberg\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"https://github.com/tophat/ormar-postgres-extensions/commits?author=etimberg\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\n```\n@all-contributors please add \u003cusername\u003e for \u003ccontribution type\u003e\n```\n\n_Find out more about All-Contributors on their website!_\n\n\n## License\n\n`ormar-postgres-extensions` is licensed under [Apache License Version 2.0](https://github.com/tophat/ormar-postgres-extensions/tree/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftophat%2Formar-postgres-extensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftophat%2Formar-postgres-extensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftophat%2Formar-postgres-extensions/lists"}