{ "info": { "author": "spapanik", "author_email": "spapanik21@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only", "Topic :: Database" ], "description": "

\n \n \"Code\n \n

\n\n# Saitama: A postgres migrations manager and test runner\n\nSaitama offers an easy way to manage migrations and run postgres unittests.\n\n## Installation\n\nThe easiest way is to use pip to install saitama.\n\n```bash\npip install --user saitama\n```\n\n## Configuration\nTo configure saitama for your project, you can use any toml file.\n\n```toml\n[tool.saitama]\nhost = \nport = \ndbname = \nuser = \npassword = \nmigrations = \ntests = \n```\n\nAll of settings are optional, and the default `host`, `port`, `dbname`, `user` and `password` are the ones specified by `psycopg2`, the default migrations directory is `migrations/`, relative to the parent directory of the toml file, and the default test directory is `tests/`, again relative to the toml file.\n\n\n## Usage\nSaitama, once installed offers a single command, `punch`, that controls the migrations and the testing. `punch` follows the GNU recommendations for command line interfaces, and offers:\n* `-h` or `--help` to print help, and\n* `-V` or `--version` to print the version\n\n### Migrations\nYou can use punch to migrate forward or backward to a specific migration. The migrations should be named `\\d+_.+\\.sql`. Backwards are considered all the migrations that the first underscore after the digits is followed by `backwards_`.\n\n```\nusage: punch migrate [-h] [-H HOST] [-P PORT] [-d DBNAME] [-u USER]\n [-p PASSWORD] [-s SETTINGS] [-D] [-f] [-b] [-y]\n [migration]\n\npositional arguments:\n migration The target migration number. If unspecified,\n punch will migrate to latest one\n\noptional arguments:\n -h, --help Show this help message and exit\n -H HOST, --host HOST The postgres host\n -P PORT, --port PORT The postgres port\n -d DBNAME, --dbname DBNAME The postgres database\n -u USER, --user USER The postgres user\n -p PASSWORD, --password PASSWORD The user's password\n -s SETTINGS, --settings SETTINGS The path to the settings file\n -D, --drop Drop the existing db and create a new one\n -f, --fake Fake the migrations up to the specified one\n -b, --backwards Backwards migration\n -y, --yes Run in non-interactive mode\n```\n\n### Test\nTesting will create a database named `test_`, run all the migrations to this database, run the tests in the test directory, and produce a report. An exit code 1 is returned if any assertion fails.\n\n```\nusage: punch test [-h] [-H HOST] [-P PORT] [-d DBNAME] [-u USER] [-p PASSWORD]\n [-s SETTINGS]\n\noptional arguments:\n -h, --help Show this help message and exit\n -H HOST, --host HOST The postgres host\n -P PORT, --port PORT The postgres port\n -d DBNAME, --dbname DBNAME The postgres database\n -u USER, --user USER The postgres user\n -p PASSWORD, --password PASSWORD The user's password\n -s SETTINGS, --settings SETTINGS The path to the settings file\n```\n\n### Writing a migration\nIn order to write a migration you just have to write an sql file:\n\n```sql\n-- /path/to/0001_initial_migration.sql\nCREATE TABLE users(\n user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n username TEXT,\n password TEXT\n);\n```\nYou can also specify a backwards migration\n\n```sql\n-- /path/to/0001_backwards_initial_migration.sql\nDROP TABLE users;\n```\n\n### Writing a test\nIn order to write a migration you just have to write an PL/pgSQL function in an sql file which returns the result of `unittest.result();`. You can make assertions by calling `unittest.assert`. The function should be in the `unittest` schema.\n\n```sql\n-- /path/to/test_name.sql\nCREATE FUNCTION unittest.bar()\n RETURNS unittest.test_result\n LANGUAGE plpgsql\nAS\n$$\nDECLARE\n _cnt INT;\nBEGIN\n INSERT\n INTO users (username, password)\n VALUES ('user', 'hashed_and_salted_password');\n\n SELECT count(*)\n FROM users\n INTO _cnt;\n\n PERFORM unittest.assert(_cnt <> 0, 'No user was created!');\n\n RETURN unittest.result();\nEND\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/spapanik/saitama", "keywords": "unit", "license": "MIT", "maintainer": "spapanik", "maintainer_email": "spapanik21@gmail.com", "name": "saitama", "package_url": "https://pypi.org/project/saitama/", "platform": "", "project_url": "https://pypi.org/project/saitama/", "project_urls": { "Homepage": "https://github.com/spapanik/saitama", "Repository": "https://github.com/spapanik/saitama" }, "release_url": "https://pypi.org/project/saitama/0.3.1/", "requires_dist": [ "psycopg2 (>=2.8,<3.0)", "toml (>=0.10,<0.11)", "pastel (>=0.1,<0.2)" ], "requires_python": ">=3.6,<4.0", "summary": "A python toolset to manage postgres migrations and testing", "version": "0.3.1" }, "last_serial": 5907704, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "1a89f7766bab40ab247c5d0293f742dc", "sha256": "dcce9a00fdc868b78a3d2c2ba5bdba05704a3e3e2acdc04e6ae2da0d291019a6" }, "downloads": -1, "filename": "saitama-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "1a89f7766bab40ab247c5d0293f742dc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 3191, "upload_time": "2019-09-18T13:52:00", "url": "https://files.pythonhosted.org/packages/a4/63/bfa9d7f1a1116b197d337935a3b552ad331198d4a440bcf909b8dedcf626/saitama-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7e3a522f36ae148a8f3cc2089178661a", "sha256": "8f11f2cb81ffe832dc8baa2d702869086dc45581d5867ec08ce130ae4013e2aa" }, "downloads": -1, "filename": "saitama-0.1.0.tar.gz", "has_sig": false, "md5_digest": "7e3a522f36ae148a8f3cc2089178661a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 2722, "upload_time": "2019-09-18T13:52:02", "url": "https://files.pythonhosted.org/packages/9b/87/6d487ad0ac70ed2a6168450282feb40d6e5c6fae642dc582277511076445/saitama-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "e3a9bb8fcde41bec0dbab5e6404bd939", "sha256": "468a45fe07cda1234e37f9b669eeb27bcb2a00cf0d76ea06a25bed116335a369" }, "downloads": -1, "filename": "saitama-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "e3a9bb8fcde41bec0dbab5e6404bd939", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 7081, "upload_time": "2019-09-24T16:07:52", "url": "https://files.pythonhosted.org/packages/13/a0/baa80e18f9351add8128aaaca2af5dfe51e2392a075924962e89411249d7/saitama-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7398d87daada3ba29cfcd9edd13479bd", "sha256": "54174e2d3cdc64e784db699d78965bfc4ae711dc78a7db453138a03ad09f0d9c" }, "downloads": -1, "filename": "saitama-0.2.0.tar.gz", "has_sig": false, "md5_digest": "7398d87daada3ba29cfcd9edd13479bd", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 5766, "upload_time": "2019-09-24T16:07:54", "url": "https://files.pythonhosted.org/packages/88/7e/19280ba10cb071dc82ac816164c80a452d723cb68197b8d8471560fa8ace/saitama-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "0a55bbb3ce9d635ca3577f5e88740d48", "sha256": "9d2e63ce24ed4f2b6d930338a9f93a293a3accd3f32aa02bc5b68f51438f88c0" }, "downloads": -1, "filename": "saitama-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "0a55bbb3ce9d635ca3577f5e88740d48", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 7101, "upload_time": "2019-09-24T17:02:41", "url": "https://files.pythonhosted.org/packages/0c/cb/289092653719b1b7dc733e3886e38727948df564ecfac101bf28f334b4e5/saitama-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2768a5d7d3d6c70c839503cdf73b498a", "sha256": "ff567e732f8d0713edab6c90796c0ea0e986644e93a77911c349f3200e02631c" }, "downloads": -1, "filename": "saitama-0.2.1.tar.gz", "has_sig": false, "md5_digest": "2768a5d7d3d6c70c839503cdf73b498a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 5796, "upload_time": "2019-09-24T17:02:43", "url": "https://files.pythonhosted.org/packages/44/d8/7bab60fbe3d5869de9bb544588ca72201550834c6dbe13df73c16c0fb994/saitama-0.2.1.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "79c0155e8705a853febefaf622417e6d", "sha256": "604ebc03033a1f02c87dcd9fb2a2125207a6c721523d6a7d8c556dcf4949b1ab" }, "downloads": -1, "filename": "saitama-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "79c0155e8705a853febefaf622417e6d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8976, "upload_time": "2019-09-25T15:17:43", "url": "https://files.pythonhosted.org/packages/8b/3f/ce0b9ab087e6137c795e60b87a6802dacfbca6f3d8c338cbb562ff0629a2/saitama-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b4ebf5d8c5b3f4b872e5b4aa5f2c01f5", "sha256": "cd58007d6ebf9310d62a31e22375b71cdb87fb06d677c8b80a4d7605bd5d2065" }, "downloads": -1, "filename": "saitama-0.3.0.tar.gz", "has_sig": false, "md5_digest": "b4ebf5d8c5b3f4b872e5b4aa5f2c01f5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 7300, "upload_time": "2019-09-25T15:17:44", "url": "https://files.pythonhosted.org/packages/de/8b/de0e278456f2b9ceb167d80918828d6e3fce6423def50e062ce3f73ed9cd/saitama-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "b60b5a15d4bfb73534e2085ab032de2b", "sha256": "a7bfe42463029c23ee2fe20e660e7da099afa2c5f28486b9df4bb95af55e7cc0" }, "downloads": -1, "filename": "saitama-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b60b5a15d4bfb73534e2085ab032de2b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 11048, "upload_time": "2019-09-30T16:02:54", "url": "https://files.pythonhosted.org/packages/03/b4/5c9178651a82b58c2c602244cc54928b79cf0ab42b42e2854f7b6f326a7e/saitama-0.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "412da4b621d945c5f074e153fc8b9521", "sha256": "fb01e247085a25e94bd01efdfc6042653ba6bad4cb4b10dc88f5065e1cc32fae" }, "downloads": -1, "filename": "saitama-0.3.1.tar.gz", "has_sig": false, "md5_digest": "412da4b621d945c5f074e153fc8b9521", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 10688, "upload_time": "2019-09-30T16:02:56", "url": "https://files.pythonhosted.org/packages/32/79/0d3583859c2a290e6cd2e466bc367c96bfa79bc9b43851d0035b38c883f2/saitama-0.3.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b60b5a15d4bfb73534e2085ab032de2b", "sha256": "a7bfe42463029c23ee2fe20e660e7da099afa2c5f28486b9df4bb95af55e7cc0" }, "downloads": -1, "filename": "saitama-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b60b5a15d4bfb73534e2085ab032de2b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 11048, "upload_time": "2019-09-30T16:02:54", "url": "https://files.pythonhosted.org/packages/03/b4/5c9178651a82b58c2c602244cc54928b79cf0ab42b42e2854f7b6f326a7e/saitama-0.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "412da4b621d945c5f074e153fc8b9521", "sha256": "fb01e247085a25e94bd01efdfc6042653ba6bad4cb4b10dc88f5065e1cc32fae" }, "downloads": -1, "filename": "saitama-0.3.1.tar.gz", "has_sig": false, "md5_digest": "412da4b621d945c5f074e153fc8b9521", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 10688, "upload_time": "2019-09-30T16:02:56", "url": "https://files.pythonhosted.org/packages/32/79/0d3583859c2a290e6cd2e466bc367c96bfa79bc9b43851d0035b38c883f2/saitama-0.3.1.tar.gz" } ] }