# (Postgres) Not an ORM
This library helps you interact with a Postgres database in Python, by writing raw SQL.
https://www.odbms.org/wp-content/uploads/2013/11/031.01-Neward-The-Vietnam-of-Computer-Science-June-2006.pdf
https://blog.codinghorror.com/object-relational-mapping-is-the-vietnam-of-computer-science/
https://news.ycombinator.com/item?id=7310077
## Basic Examples
```python
from pydantic import BaseModel
from pnorm import PostgresClient, PostgresCredentials
creds = PostgresCredentials(host="", port=5432, user="", password="", dbname="")
client = PostgresClient(creds)
class User(BaseModel):
name: str
age: int
# If we *know* there is exactly one "john"
john: User = client.get(User, "select * from users where name = %(name)s", {"name": "john"})
# Get the first "mike" or return None
mike: User | None = client.find(Users, "select * from users where name = %(name)s, {"name": "mike"})
# Get all results
adults: list[User] = client.select(User, "select * from users where age >= 18")
# delete adults
client.execute("delete from users where age >= 18")
# insert into table
client.execute_values(
"insert into users (name, age) values (%(name)s, %(age)s),
[
User(name="sally", age=20),
User(name="daniel", age=21)
]
)
```
## Keep connection alive
```python
with client.start_session(schema="admin") as session:
# Connection end
# > Set the default schema to "admin"
session.execute("create table users (name varchar, age integer)")
client.execute_values(
"insert into users (name, age) values (%(name)s, %(age)s),
[
User(name="sally", age=20),
User(name="daniel", age=21)
]
)
# Connection end
```
## Create a transaction
This example, retrieves a user from the users table, deletes the user, in python increments the user's age, then inserts the user back into the DB. Because this is in a transaction, the user will exist in the database with it's previous age (in case of a failure) or exist in the database with their new age.
```python
person = transaction.get(User, "select * from users where name = %(name)s", {"name": "mike"})
with client.create_transaction() as transaction:
# Transaction start
transaction.execute("delete from users where name = %(name)s", {"name": "mike"})
person.age += 1
transaction.execute("insert into users (name, age) (%(name)s, %(age)s))", person)
# Transaction end
```
Of course you could do this all in SQL with an update statement.
Inspired by
https://github.com/jmoiron/sqlx
https://github.com/dagster-io/dagster/blob/master/python_modules/libraries/dagster-aws/dagster_aws/redshift/resources.py
https://github.com/jmoiron/sqlx
https://jmoiron.github.io/sqlx/
Raw data
{
"_id": null,
"home_page": "https://github.com/alrudolph/pnorm",
"name": "pnorm",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.11",
"maintainer_email": null,
"keywords": null,
"author": "Alex Rudolph",
"author_email": "alex3rudolph@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/bb/77/a2c5d32dbfb54b2ca549f76c152aaa2c1733c817268851a26ba3b4536483/pnorm-0.0.0.6.tar.gz",
"platform": null,
"description": "# (Postgres) Not an ORM\n\nThis library helps you interact with a Postgres database in Python, by writing raw SQL. \n\nhttps://www.odbms.org/wp-content/uploads/2013/11/031.01-Neward-The-Vietnam-of-Computer-Science-June-2006.pdf\nhttps://blog.codinghorror.com/object-relational-mapping-is-the-vietnam-of-computer-science/\nhttps://news.ycombinator.com/item?id=7310077\n\n## Basic Examples\n\n```python\nfrom pydantic import BaseModel\n\nfrom pnorm import PostgresClient, PostgresCredentials\n\ncreds = PostgresCredentials(host=\"\", port=5432, user=\"\", password=\"\", dbname=\"\")\n\nclient = PostgresClient(creds)\n\nclass User(BaseModel):\n name: str\n age: int\n\n# If we *know* there is exactly one \"john\"\njohn: User = client.get(User, \"select * from users where name = %(name)s\", {\"name\": \"john\"})\n\n# Get the first \"mike\" or return None\nmike: User | None = client.find(Users, \"select * from users where name = %(name)s, {\"name\": \"mike\"})\n\n# Get all results\nadults: list[User] = client.select(User, \"select * from users where age >= 18\")\n\n# delete adults\nclient.execute(\"delete from users where age >= 18\")\n\n# insert into table\nclient.execute_values(\n \"insert into users (name, age) values (%(name)s, %(age)s),\n [\n User(name=\"sally\", age=20),\n User(name=\"daniel\", age=21)\n ]\n)\n```\n\n## Keep connection alive\n\n```python\nwith client.start_session(schema=\"admin\") as session:\n # Connection end\n # > Set the default schema to \"admin\"\n\n session.execute(\"create table users (name varchar, age integer)\")\n client.execute_values(\n \"insert into users (name, age) values (%(name)s, %(age)s),\n [\n User(name=\"sally\", age=20),\n User(name=\"daniel\", age=21)\n ]\n )\n \n # Connection end\n```\n\n## Create a transaction\n\nThis example, retrieves a user from the users table, deletes the user, in python increments the user's age, then inserts the user back into the DB. Because this is in a transaction, the user will exist in the database with it's previous age (in case of a failure) or exist in the database with their new age.\n\n```python\nperson = transaction.get(User, \"select * from users where name = %(name)s\", {\"name\": \"mike\"})\n\nwith client.create_transaction() as transaction:\n # Transaction start\n\n transaction.execute(\"delete from users where name = %(name)s\", {\"name\": \"mike\"})\n person.age += 1\n transaction.execute(\"insert into users (name, age) (%(name)s, %(age)s))\", person)\n \n # Transaction end\n```\n\nOf course you could do this all in SQL with an update statement.\n\n\nInspired by\nhttps://github.com/jmoiron/sqlx\n\n\nhttps://github.com/dagster-io/dagster/blob/master/python_modules/libraries/dagster-aws/dagster_aws/redshift/resources.py\nhttps://github.com/jmoiron/sqlx\nhttps://jmoiron.github.io/sqlx/\n",
"bugtrack_url": null,
"license": null,
"summary": "(Postgres) Not an ORM",
"version": "0.0.0.6",
"project_urls": {
"Homepage": "https://github.com/alrudolph/pnorm",
"Repository": "https://github.com/alrudolph/pnorm"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "150139b705e3e1e5b4d22852a73337e917769594f5350c5b57eb5cb2beb7eb6c",
"md5": "a1d474d13398290fd177dd5cf9593385",
"sha256": "e0283ef7758165a829f6c2af17c058396aef07d2ec0fd40dbe03ae17bfbad7f6"
},
"downloads": -1,
"filename": "pnorm-0.0.0.6-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a1d474d13398290fd177dd5cf9593385",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.11",
"size": 23603,
"upload_time": "2024-08-07T19:39:31",
"upload_time_iso_8601": "2024-08-07T19:39:31.117254Z",
"url": "https://files.pythonhosted.org/packages/15/01/39b705e3e1e5b4d22852a73337e917769594f5350c5b57eb5cb2beb7eb6c/pnorm-0.0.0.6-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "bb77a2c5d32dbfb54b2ca549f76c152aaa2c1733c817268851a26ba3b4536483",
"md5": "b75f75b39a9f7697790bd5ff8ceca284",
"sha256": "c551f707e78c779c2d44f9cd64b35e1989e3b31975f808ac5327932a612d24a0"
},
"downloads": -1,
"filename": "pnorm-0.0.0.6.tar.gz",
"has_sig": false,
"md5_digest": "b75f75b39a9f7697790bd5ff8ceca284",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.11",
"size": 18412,
"upload_time": "2024-08-07T19:39:32",
"upload_time_iso_8601": "2024-08-07T19:39:32.013772Z",
"url": "https://files.pythonhosted.org/packages/bb/77/a2c5d32dbfb54b2ca549f76c152aaa2c1733c817268851a26ba3b4536483/pnorm-0.0.0.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-07 19:39:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "alrudolph",
"github_project": "pnorm",
"github_not_found": true,
"lcname": "pnorm"
}