{"id":17862823,"url":"https://github.com/alexey-sveshnikov/pyrus-orm","last_synced_at":"2025-08-14T14:31:23.992Z","repository":{"id":145548144,"uuid":"575153248","full_name":"alexey-sveshnikov/pyrus-orm","owner":"alexey-sveshnikov","description":"Simple ORM for Pyrus","archived":false,"fork":false,"pushed_at":"2023-03-23T13:51:34.000Z","size":26,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-08T00:46:02.719Z","etag":null,"topics":["client","orm","pyrus","python"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pyrus-orm/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexey-sveshnikov.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-06T21:52:09.000Z","updated_at":"2024-10-24T07:11:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"405ec174-fc9a-4109-beb9-7ff48af27f4d","html_url":"https://github.com/alexey-sveshnikov/pyrus-orm","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexey-sveshnikov%2Fpyrus-orm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexey-sveshnikov%2Fpyrus-orm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexey-sveshnikov%2Fpyrus-orm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexey-sveshnikov%2Fpyrus-orm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexey-sveshnikov","download_url":"https://codeload.github.com/alexey-sveshnikov/pyrus-orm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229834882,"owners_count":18131525,"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":["client","orm","pyrus","python"],"created_at":"2024-10-28T08:55:08.414Z","updated_at":"2024-12-15T15:18:39.381Z","avatar_url":"https://github.com/alexey-sveshnikov.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"pyrus-orm\n=========\n\nRadically simple, django/peewee-like, easy and incomplete ORM for [Pyrus](https://pyrus.com).\n\nWith pyrus-orm, you can read, create and modify [tasks](https://pyrus.com/en/help/api/models#form-registry-task).\n\nWorks with [pyrus-api](https://github.com/simplygoodsoftware/pyrusapi-python) under the hood.\n\n### This is an early development version\n\n### Features:\n\n- Define models with:\n    - [x] simple fields (text, number, dates, checkmark, flag, ...)\n    - [x] catalog fields, single item\n    - [ ] catalog fields, multiple items\n    - [ ] \"title\" fields (pyrus-orm ignores the nested structure of 'title' fields, all its contents are treated as usual root-level fields)\n    - [x] multiple choice fields (without nested fields at this moment)\n- Operations with models:\n    - [x] Create and save\n    - [x] Read from registry by ID\n    - [x] Modify and save changes\n- Filtering:\n    - [x] by include_archived and steps fields\n    - [x] by value of simple or catalog fields\n    - [ ] less than, greater than\n    - [ ] value in a list\n    - [ ] ranges\n\nInstallation\n-----------\n\n```shell\npip install pyrus-orm\n```\n\nExamples\n-------\n\n\n### Define model and initialize\n\n```python\n\nclass Book(PyrusModel):\n    title = TextField(1)  # 1 is a field ID in pyrus's form\n    time = TimeField(2)\n    date = DateField(3)\n    number = NumericField(4)\n    round_number = IntegerField(5)\n    author = CatalogField(6, catalog=\u003ccatalog id\u003e)\n\n    class Meta:\n        form_id = \u003cform_id\u003e\n\n\npyrus_api = PyrusAPI(...)\nsession = PyrusORMSession(pyrus_api)\n\nset_session_global(session)\n```\n\n\n### Create item\n\n```python\nbook = Book(\n    title='Don Quixote',\n    date='1605-01-01',\n    author=Book.author.find({'Name': 'Alonso Fernández de Avellaneda'})\n)\n\nbook.save()\n\nbook.id\n\u003e\u003e\u003e \u003ctask_id\u003e\n```\n\n\n### Read and modify item\n\n```python\nbook = Book.objects.get(id=...)\n\n# simple field\nbook.title\n\u003e\u003e\u003e 'Don Quixote'\nbook.title = 'Don Quixote, Part Two'\nbook.save('title changed')\n\n# catalog field\nbook.author\n\u003e\u003e\u003e CatalogItem(item_id=..., values={'Name': 'Alonso Fernández de Avellaneda'})  # values comes from the catalog definition\n\nbook.author.find_and_set({'Name': 'Miguel de Cervantes'})  # may raise ValueError if no value found\nbook.save('changed an author to the real one')\n```\n\n### Catalog Enum fields\n\nEnums can be mapped to catalog items by ID or by custom property name.\n\n#### Enums mapped to specific catalog items ID\n\nNo catalog lookups are preformed on reading or writing of such fields.\n\n```python\nclass Genre(Enum):\n    fiction = 100001\n    nonfiction = 100002\n\n\nclass Book(PyrusModel):\n    genre = CatalogEnumField(\u003cfield_id\u003e, catalog_id=\u003ccatalog_id\u003e, enum=Genre, id_field='item_id')\n\nbook = Book.objects.get(id=...)\n\nbook.genre\n\u003e\u003e\u003e Genre.fiction\n\nbook.genre = Genre.nonfiction\nbook.save()\n\nbook.genre\n\u003e\u003e\u003e Genre.nonfiction\n```\n\n\n#### Enums mapped to catalog item properties\n\n(imagine book has a property 'media' with field 'Name')\n\n```python\nclass Media(Enum):\n    paper = 'paper'\n    papirus = 'papirus'\n    pdf = 'pdf'\n\nclass Book(PyrusModel):\n    media = CatalogEnumField(\u003cfield_id\u003e, catalog_id=\u003ccatalog_id\u003e, enum=Genre, id_field='Name')\n```\n\n### Filtering\n\nOnly basic filtering is supported:\n\n```python\n\nBook.objects.get_filtered(\n    title='Don Quixote',\n)\n\u003e\u003e\u003e [Book(...), ...]\n\n\nBook.objects.get_filtered(\n    genre=Book.genre.find({'Name': 'Fiction'})\n)\n\u003e\u003e\u003e [Book(...), ...]\n\nBook.objects.get_filtered(\n    ...\n    include_archived=True,\n    steps=[1, 2],\n)\n\u003e\u003e\u003e [Book(...), ...]\n```\n\n\n### Catalog fields, all the API\n```python\n# Read values\n\n# Non-empty value\nbook.author\n\u003e\u003e\u003e CatalogItem(item_id=..., values={\u003cyour custom values here\u003e})\n\nassert bool(book.author) == True\n\n# Empty value\nbook.author\n\u003e\u003e\u003e CatalogEmptyValue()\n\nassert bool(book.author) == False\n\n\n# Get all possible values (works for empty fields as well)\nbook.author.catalog()\n\u003e\u003e\u003e [CatalogItem(...), CatalogItem(...), ...]\n\n\n# Find a value in a catalog\nnew_author = book.author.catalog().find({'Name': 'Miguel de Cervantes'})\nnew_author\n\u003e\u003e\u003e CatalogItem(item_id=..., values={'Name': 'Miguel de Cervantes'})  # or None\n\nbook.author = new_author\nbook.save()\n\n\n# Find and set shortcut\nbook.author.catalog().find_and_set({'Name': 'William Shakespeare'})\n\nbook.author.find_and_set({'Name': 'NonExistent'})\n\u003e\u003e\u003e ValueError raised\n\n\n# Set value to a specific item_id\nbook.author = CatalogItem(item_id=123456)\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexey-sveshnikov%2Fpyrus-orm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexey-sveshnikov%2Fpyrus-orm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexey-sveshnikov%2Fpyrus-orm/lists"}