{"id":43448490,"url":"https://github.com/aleasoluciones/infpostgresql","last_synced_at":"2026-02-03T01:15:35.878Z","repository":{"id":137627338,"uuid":"350673623","full_name":"aleasoluciones/infpostgresql","owner":"aleasoluciones","description":"🗄️ PostgreSQL infrastructure (wrapper for psycopg)","archived":false,"fork":false,"pushed_at":"2025-11-24T11:35:52.000Z","size":81,"stargazers_count":0,"open_issues_count":2,"forks_count":1,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-11-27T22:53:47.421Z","etag":null,"topics":["library","postgresql","psycopg","python3","wrapper"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aleasoluciones.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-03-23T10:42:15.000Z","updated_at":"2025-11-24T10:18:07.000Z","dependencies_parsed_at":"2025-11-27T12:07:34.676Z","dependency_job_id":null,"html_url":"https://github.com/aleasoluciones/infpostgresql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aleasoluciones/infpostgresql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleasoluciones%2Finfpostgresql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleasoluciones%2Finfpostgresql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleasoluciones%2Finfpostgresql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleasoluciones%2Finfpostgresql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aleasoluciones","download_url":"https://codeload.github.com/aleasoluciones/infpostgresql/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleasoluciones%2Finfpostgresql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29025801,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T00:53:18.321Z","status":"ssl_error","status_checked_at":"2026-02-03T00:51:45.186Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["library","postgresql","psycopg","python3","wrapper"],"created_at":"2026-02-03T01:15:35.362Z","updated_at":"2026-02-03T01:15:35.872Z","avatar_url":"https://github.com/aleasoluciones.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# infpostgresql\n\n[![CI](https://github.com/aleasoluciones/infpostgresql/actions/workflows/ci.yml/badge.svg)](https://github.com/aleasoluciones/infpostgresql/actions/workflows/ci.yml)\n![Python versions supported](https://img.shields.io/badge/supports%20python-3.9%20|%203.10%20|%203.11-blue.svg)\n\nWrapper for the [psycopg](https://www.psycopg.org) library using Python 3.\n\n## Development\n\n### Setup\n\nCreate a virtual environment, install dependencies and load environment variables.\n\n```python\nmkvirtualenv infpostgresql -p $(which python3)\ndev/setup_venv.sh\nsource dev/env_develop\n```\n\nRun a PostgreSQL Docker container.\n\n```python\ndev/start_local_dependencies.sh\n```\n### Debug.\n\nYou can now debug queries made by setting the POSTGRES_DEBUG env variable as True\n\nTo set the variable you can do a\n```bash\nexport POSTGRES_DEBUG=True\n```\nor set the varaible in `dev/env_develop`\n**Important**: true with Capital case **T**rue\n\n\n### Running tests, linter \u0026 formatter and configure git hooks\n\nNote that project uses Alea's [pydevlib](https://github.com/aleasoluciones/pydevlib), so take a look at its README to see the available commands.\n\n## Internals\n\nIn the `execute()` method of the `PostgresClient` class, we're enclosing the `cursor.fetchall()` call in a try-except block. The reason is that that method only makes sense if the database returns data. Otherwise it will throw a `ProgrammingError` exception, which we intercept. Any other exception is allowed to bubble up, so we can still know what's wrong from the outside.\n\nThis design is for the sake of homogeneity, so we can aways use the `execute()` method the same, no matter what kind of SQL statement is being executed.\n\n## infpostgresql client API\n\nBelow is described the public API that this library provides.\n\nThe client may be initialized using the factory with a database URI and an optional argument `use_dict_cursor` which indicates how the output will be returned.\n\n\u003e postgres_client = factory.**postgres_client_from_connection_uri**(*database_uri*, *use_dict_cursor=False*)\n\n### execute()\n\nExecutes a SQL query and returns the result. Passing parameters is possible by using `%s` placeholders in the SQL query, and passing a sequence of values as the second argument of the function.\n\n\u003e postgresql_client.**execute**(*query*, *params*)\n\n➡️ Parameters\n\n- **query**: `str`\n- **params** (optional): `tuple\u003cany\u003e`. Defaults to `None`.\n\n⬅️ Returns a list of tuples or a list of dictionaries, depending on the value of `use_dict_cursor`. Each item contains a row of results.\n\n💥 Throws any Postgres error converted to CamelCase (available [here](https://www.postgresql.org/docs/12/errcodes-appendix.html), some examples in the [integration tests](integration_specs/postgresql_spec.py)).\n\n#### Usage example\n\n```python\nfrom infpostgresql import factory\n\npostgres_uri = 'postgres://username:password@host:port/databasename'\npostgres_client = factory.postgres_client_from_connection_uri(postgres_uri)\n\nquery = 'SELECT (name, surname, age) FROM users WHERE age \u003c %s AND active = %s;'\nparams = (30, True, )\n\nresult = postgres_client.execute(query, params)\n\n# [\n#   ('Ann', 'White', 18, ),\n#   ('Axel', 'Schwarz', 21, ),\n#   ('Camille', 'Rouge', '27', )\n# ]\n```\n\n#### Another usage example, with the dictionary cursor\n\n```python\nfrom infpostgresql import factory\n\npostgres_uri = 'postgres://username:password@host:port/databasename'\npostgres_client = factory.postgres_client_from_connection_uri(postgres_uri, use_dict_cursor=True)\n\nquery = 'SELECT (name, surname, age) FROM users WHERE age \u003c %s AND active = %s;'\nparams = (30, True, )\n\nresult = postgres_client.execute(query, params)\n\n# [\n#   {'name': 'Ann', 'surname': 'White', 'age': 18},\n#   {'name': 'Axel', 'surname': 'Schwarz', 'age': 21},\n#   {'name': 'Camille', 'surname': 'Rouge', 'age': 27}\n# ]\n```\n\n### execute_with_lock()\n\nWorks like the normal execute, but keeps a table locked while performing the query.\n\n\u003e postgresql_client.**execute_with_lock**(*query*, *table*, *params*)\n\n➡️ Parameters\n\n- **query**: `str`\n- **table**: `str`\n- **params** (optional): `tuple\u003cany\u003e`. Defaults to `None`.\n\n⬅️ Returns a list of tuples or a list of dictionaries, depending on the value of `use_dict_cursor`. Each item contains a row of results.\n\n💥 Throws any Postgres error converted to CamelCase (available [here](https://www.postgresql.org/docs/12/errcodes-appendix.html), some examples in the [integration tests](integration_specs/postgresql_spec.py)).\n\n### execute_with_transactions()\n\nExecutes multiple SQL queries. Each query can be sent along with their parameters. If any of them fails, the whole process is reversed to ensure the integrity of the transaction.\n\n\u003e postgresql_client.**execute_with_transactions**(*list_of_queries_with_params*)\n\n➡️ Parameters\n\n- **list_of_queries_with_params**: `list\u003ctuple\u003cstr, tuple\u003cany\u003e\u003e\u003e`\n\n⬅️ Returns nothing\n\n💥 Throws any Postgres error converted to CamelCase (available [here](https://www.postgresql.org/docs/12/errcodes-appendix.html), some examples in the [integration tests](integration_specs/postgresql_spec.py)).\n\n#### Usage example\n\n```python\nfrom infpostgresql import factory\n\npostgres_uri = 'postgres://username:password@host:port/databasename'\npostgres_client = factory.postgres_client_from_connection_uri(postgres_uri)\n\nquery_1 = 'UPDATE bank_account SET balance = balance - %s WHERE name = %s;'\nparams_1 = (100, 'Jack', )\noperation_1 = (query_1, params_1, )\n\nquery_2 = 'INSERT INTO bank_account(name, balance) VALUES (%s, %s);'\nparams_2 = ('Kate', 100, )\noperation_2 = (query_2, params_2, )\n\nresult = postgres_client.execute_with_transactions([operation_1, operation_2])\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleasoluciones%2Finfpostgresql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faleasoluciones%2Finfpostgresql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleasoluciones%2Finfpostgresql/lists"}