{"id":15066760,"url":"https://github.com/mcculloh213/alchemist-stack","last_synced_at":"2026-02-09T11:01:34.171Z","repository":{"id":57409506,"uuid":"130711421","full_name":"mcculloh213/alchemist-stack","owner":"mcculloh213","description":"A Generic Model-Repository-Database stack for use with SQL Alchemy","archived":false,"fork":false,"pushed_at":"2018-05-16T14:01:58.000Z","size":89,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-27T22:17:46.929Z","etag":null,"topics":["database","python3","sqlalchemy"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/alchemist-stack/","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/mcculloh213.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.txt","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-23T14:40:46.000Z","updated_at":"2018-05-16T14:01:59.000Z","dependencies_parsed_at":"2022-08-24T18:50:53.338Z","dependency_job_id":null,"html_url":"https://github.com/mcculloh213/alchemist-stack","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mcculloh213/alchemist-stack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcculloh213%2Falchemist-stack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcculloh213%2Falchemist-stack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcculloh213%2Falchemist-stack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcculloh213%2Falchemist-stack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcculloh213","download_url":"https://codeload.github.com/mcculloh213/alchemist-stack/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcculloh213%2Falchemist-stack/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267882208,"owners_count":24160070,"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","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["database","python3","sqlalchemy"],"created_at":"2024-09-25T01:11:46.814Z","updated_at":"2026-02-09T11:01:34.072Z","avatar_url":"https://github.com/mcculloh213.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# alchemist-stack\r\n**Package Author**: H.D. 'Chip' McCullough IV\r\n\r\n**Last Updated**: April 23rd, 2018\r\n\r\n**Description**:\\\r\nA Flexible Model-Repository-Database stack for use with SQL Alchemy\r\n\r\n## Overview\r\nAlchemist Stack is intended to be a thread-safe, multi-session/multi-connection \r\n\r\n## Motivation\r\n\r\nThe motivation for this package started partly out of API documentation procrastination, and partly from noticing that \r\nthe API I was documenting created a single connection on startup that persisted though the life of the API. In theory, \r\n(kind of) works for Development environments, and may even (kind of) work in Production environments under light load \r\n(the operating words being \"light load\"). In practice, it doesn't make sense for the database to create a connection \r\npool, have the server spawn N worker threads, then take a single connection from the connection pool, and use that \r\nsingle connection for all N worker threads. Under heavy load, that single connection is a bottleneck that would have to \r\nserve all requests coming in.\r\n\r\nThus, the problem is how do we create a multi-connection environment to alleviate the bottleneck single-connection \r\nenvironment that is already in place? Astoundingly, SQL Alchemy already has that solved, with their Session API \r\n(/sarcasm). Using the Session API, Alchemist Stack provides a base Repository object, RepositoryBase, that (at the time \r\nof writing) abstracts the Session API to the four CRUD operations (Create, Read, Update, and Delete). While this does \r\nleave the developer with a quite a bit to finish implementing, it provides a quality scaffolding to get ~80% (don't \r\nfact check me on that number) of all web app projects up and running as quickly as possible.\r\n\r\nNow, this leaves one last issue: SQL Alchemy's Session API isn't thread safe. This is solved in two ways:\r\n  1. The RepositoryBase contains an abstract class method, `instance`, which must be implemented (or not) by the \r\n  child class.\r\n  2. The RepositoryBase contains a function `_create_thread_safe_session()`, which creates a thread-local Session, \r\n  which any thread can utilize through the life cycle of that Session.\r\n\r\nWhile Alchemist Stack was implemented with the \r\n\r\n### The RepositoryBase `instance` Method\r\n\r\nThe `instance` method, which takes in a Context object, returns a new instance of the implemented repository. That \r\ninstance holds the  Context used to connect to and query the database. \r\n\r\nIn the context of an API call, it is safe to create a new instance at the beginning of the request, run a CRUD \r\noperation, create and use a raw Session, do what you need, commit everything to the database, handle any errors \r\n(because no software is perfect), then dispose of the instance at the end of the request.\r\n\r\nImplementation of the `instance` method is incredibly straightforward, whether you intend to use it, or not. To \r\nimplement it for use,\r\n\r\n```python\r\nT = TypeVar('T', bound='your class here')\r\n    @classmethod\r\n    def instance(cls, context: Context) -\u003e T:\r\n        return cls(context=context)\r\n```\r\nAnd you're done! Likewise, to implement it for !use,\r\n```python\r\n    @classmethod\r\n    def instance(cls, context: Context) -\u003e NoReturn:\r\n        pass\r\n```\r\nOf course, I would recommend implementing the `instance` method, if not for full flexibility, then for completion, \r\nbut I can't tell you how to code.\r\n\r\n### The RepositoryBase `_create_thread_safe_session()` Function\r\n\r\nSometimes, just managing a single instance of a repository and Session isn't enough. Depending on how objects in an \r\napplication interact, it may be more prudent to give multiple repositories access to the same Session, which is where \r\nSQL Alchemy's `scoped_session(...)` and the RepositoryBase's `_create_thread_safe_session()` come in. Creating a scoped \r\nSession creates a global Session object than any thread has access to.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcculloh213%2Falchemist-stack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcculloh213%2Falchemist-stack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcculloh213%2Falchemist-stack/lists"}