{ "info": { "author": "William Jackson", "author_email": "william@subtlecoolness.com", "bugtrack_url": null, "classifiers": [], "description": "# fort\n\n*The Python database micropackage*\n\n-----\n\n**fort** is a thin database wrapper for programmers who love to write SQL. Use it when SQLAlchemy is too much.\n\n## Usage\n\nStart by initializing an object for your database, providing a connection string:\n\n```python\nimport fort\n\ndb = fort.PostgresDatabase('postgres://user:password@host/database')\n```\n\nEach of fort's database classes provides a small set of methods that makes working with SQL simple. You can immediately\nbegin making queries to the database:\n\n```python\nimport uuid\n\ndb.u('CREATE TABLE widgets (id uuid PRIMARY KEY, name text)')\n\nmy_id = uuid.uuid4()\ndb.u('INSERT INTO widgets (id, name) VALUES (%(id)s, %(name)s)', {'id': my_id, 'name': 'Thingy'})\n\nfor row in db.q('SELECT id, name FROM widgets'):\n print(row['id'], row['name'])\n\nmy_widget = db.q_one('SELECT id, name FROM widgets WHERE id = %(id)s', {'id': my_id})\nprint(my_widget['name'])\n\nmy_widget_name = db.q_val('SELECT name FROM widgets WHERE id = %(id)s', {'id': my_id})\nprint(my_id, my_widget_name)\n```\n\nUsing one of fort's database classes directly is fine, but it is better to consolidate your SQL statements by\nsubclassing one of fort's classes and adding your own methods:\n\n```python\nclass MyDatabase(fort.PostgresDatabase):\n\n def migrate(self):\n self.u('CREATE TABLE widgets (id uuid PRIMARY KEY, name text)')\n\n def add_widget(self, widget_name: str) -> uuid.UUID:\n new_id = uuid.uuid4()\n sql = 'INSERT INTO widgets (id, name) VALUES (%(id)s, %(name)s)'\n params = {'id': new_id, 'name': widget_name}\n self.u(sql, params)\n return new_id\n\n def list_widgets(self) -> List[Dict]:\n return self.q('SELECT id, name FROM widgets')\n\n def get_widget(self, widget_id: uuid.UUID) -> Optional[Dict]:\n sql = 'SELECT id, name FROM widgets WHERE id = %(id)s'\n return self.q_one(sql, {'id': widget_id})\n\n def get_widget_name(self, widget_id: uuid.UUID) -> Optional[str]:\n sql = 'SELECT name FROM widgets WHERE id = %(id)s'\n return self.q_val(sql, {'id': widget_id})\n\ndb = MyDatabase('postgres://user:password@host/database')\ndb.migrate()\n\nmy_id = db.add_widget('Thingy')\n\nfor widget in db.list_widgets():\n print(widget['id', widget['name']])\n\nmy_widget = db.get_widget(my_id)\nprint(my_widget['id'], my_widget['name'])\n\nmy_widget_name = db.get_widget_name(my_id)\nprint(my_id, my_widget_name)\n```\n\n## Database class methods\n\nThe following methods come with every fort database class:\n\n```python\ndef u(self, sql: str, params: Dict = None) -> int: ...\n \"\"\"\n Execute a statement and return the number of rows affected.\n Use this method for CREATE, INSERT, and UPDATE statements.\n \"\"\"\n\ndef q(self, sql: str, params: Dict = None) -> List[Dict]: ...\n \"\"\"\n Execute a statement and return all results.\n Use this method for SELECT statements.\n \"\"\"\n\ndef q_one(self, sql: str, params: Dict = None) -> Optional[Dict]: ...\n \"\"\"\n Execute a statement and return the first result.\n If there are no results, return `None`.\n \"\"\"\n\ndef q_val(self, sql: str, params: Dict = None) -> Any: ...\n \"\"\"\n Execute a statement and return the value in the first column of the first result.\n If there are no results, return `None`.\n \"\"\"\n```\n\n## Notes on specific database classes\n\n### PostgresDatabase\n\nUse `PostgresDatabase` to connect to a PostgreSQL database. Use `pyformat` [paramstyle][a] for all your statements.\nYour connection string will be passed directly to [`psycopg2.connect()`][b].\n\n### SQLiteDatabase\n\nUse `SQLiteDatabase` to connect to an SQLite database. Use `named` [paramstyle][a] for all your statements. Your\nconnection string will be passed directly to [`sqlite3.connect()`][c].\n\n[a]: https://www.python.org/dev/peps/pep-0249/#paramstyle\n[b]: http://initd.org/psycopg/docs/module.html#psycopg2.connect\n[c]: https://docs.python.org/3/library/sqlite3.html#sqlite3.connect\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/williamjacksn/fort", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "fort", "package_url": "https://pypi.org/project/fort/", "platform": "", "project_url": "https://pypi.org/project/fort/", "project_urls": { "Homepage": "https://github.com/williamjacksn/fort" }, "release_url": "https://pypi.org/project/fort/0.0.7/", "requires_dist": null, "requires_python": "", "summary": "The Python database micropackage", "version": "0.0.7" }, "last_serial": 5462264, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "222c783ce28f368897f878865e5dc07f", "sha256": "365e626ae21610611e6ad7ceef14afe2d1ea716cd166a53da942c3fe7b5e0db1" }, "downloads": -1, "filename": "fort-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "222c783ce28f368897f878865e5dc07f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 1895, "upload_time": "2019-06-24T20:17:56", "url": "https://files.pythonhosted.org/packages/35/b2/8eff78fe7744722d2e86df37c91f88d4ecaa0fabcd56e5b50745eb0117f9/fort-0.0.1-py3-none-any.whl" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "b16b46a5b8d50f5aa429a3208e48f568", "sha256": "14e9dee5e74c8858e7e720ee9aefd3423b9657e144fa376584af004590897a32" }, "downloads": -1, "filename": "fort-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "b16b46a5b8d50f5aa429a3208e48f568", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 1165, "upload_time": "2019-06-24T20:49:50", "url": "https://files.pythonhosted.org/packages/72/db/221a8880c08f440e8298652e15931804ce3fcf2f0684c79886d99ae57cf2/fort-0.0.2-py3-none-any.whl" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "d0d3a91d69eb1c4ba00d8fa3adee46f4", "sha256": "a2cbb748783034783843b026b42c25d3e1fe88aaf696015d8e2f609a0b1ca200" }, "downloads": -1, "filename": "fort-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "d0d3a91d69eb1c4ba00d8fa3adee46f4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 2776, "upload_time": "2019-06-24T21:13:54", "url": "https://files.pythonhosted.org/packages/09/54/b41e6e41c2f22ad8dc73306d641919ffc9f48e161aeb47b62cd6273ff872/fort-0.0.3-py3-none-any.whl" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "d7638270c38540b3a8ee7dd9be8a827a", "sha256": "d3d7f44d2381274a0c67ee0d9ea22af059b7a6574fa69b6626bd77ca122711bd" }, "downloads": -1, "filename": "fort-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "d7638270c38540b3a8ee7dd9be8a827a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 2298, "upload_time": "2019-06-25T04:17:06", "url": "https://files.pythonhosted.org/packages/f7/97/ad3f6d52785ee980e7d4bc06fb353a86a03306daefc798b0948fab17ee3a/fort-0.0.4-py3-none-any.whl" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "74f33a86da174dac620df1dd6c1589bd", "sha256": "2f51c7ecdbc81aee10eea9139c35523132650aa1752780d9477c93127565e903" }, "downloads": -1, "filename": "fort-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "74f33a86da174dac620df1dd6c1589bd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4192, "upload_time": "2019-06-25T15:47:12", "url": "https://files.pythonhosted.org/packages/97/26/35c314e54081247f8b2e8832040be0476ffbf2783afe86db69fd42f0d5e1/fort-0.0.5-py3-none-any.whl" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "944ad4b38e83719bb57ddf5b5cbb1461", "sha256": "6b06643811c4f0a5e47ddb1f1f9b40b27c5a464da7fee43770cae4cdf90e5fec" }, "downloads": -1, "filename": "fort-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "944ad4b38e83719bb57ddf5b5cbb1461", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4252, "upload_time": "2019-06-25T19:06:37", "url": "https://files.pythonhosted.org/packages/bb/52/1a5e912ba90f26a9611e54809de9435108d3500a74c187508c42d072a101/fort-0.0.6-py3-none-any.whl" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "1c4504e8b60d6716b2a10ed77ae33879", "sha256": "aa723c795a284c55cba01892ab737b8caec7a98bda86436008d613a5fd7686bf" }, "downloads": -1, "filename": "fort-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "1c4504e8b60d6716b2a10ed77ae33879", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4253, "upload_time": "2019-06-28T15:29:01", "url": "https://files.pythonhosted.org/packages/73/69/d40cd71802615102bd43972b8a29dec058cc9bd75119cf95979b4545f1c9/fort-0.0.7-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1c4504e8b60d6716b2a10ed77ae33879", "sha256": "aa723c795a284c55cba01892ab737b8caec7a98bda86436008d613a5fd7686bf" }, "downloads": -1, "filename": "fort-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "1c4504e8b60d6716b2a10ed77ae33879", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4253, "upload_time": "2019-06-28T15:29:01", "url": "https://files.pythonhosted.org/packages/73/69/d40cd71802615102bd43972b8a29dec058cc9bd75119cf95979b4545f1c9/fort-0.0.7-py3-none-any.whl" } ] }