{
"info": {
"author": "Jean Cochrane",
"author_email": "jean@jeancochrane.com",
"bugtrack_url": null,
"classifiers": [
"Development Status :: 4 - Beta",
"Environment :: Plugins",
"Environment :: Web Environment",
"Framework :: Pytest",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Testing"
],
"description": "# pytest-flask-sqlalchemy\n\n[](https://travis-ci.org/jeancochrane/pytest-flask-sqlalchemy) \n\nA [pytest](https://docs.pytest.org/en/latest/) plugin providing fixtures for running tests in\ntransactions using [Flask-SQLAlchemy](http://flask-sqlalchemy.pocoo.org/latest/).\n\n## Contents\n\n- [**Motivation**](#motivation)\n- [**Quick examples**](#quick-examples)\n- [**Usage**](#usage)\n - [Installation](#installation)\n - [From PyPi](#from-pypi)\n - [Development version](#development-version)\n - [Supported backends](#supported-backends)\n - [Configuration](#configuration)\n - [Conftest setup](#conftest-setup)\n - [Test configuration](#test-configuration)\n - [`mocked-engines`](#mocked-engines)\n - [`mocked-sessions`](#mocked-sessions)\n - [`mocked-sessionmakers`](#mocked-sessionmakers)\n - [Writing transactional tests](#writing-transactional-tests)\n - [Fixtures](#fixtures)\n - [`db_session`](#db_session)\n - [`db_engine`](#db_engine)\n - [Enabling transactions without fixtures](#enabling-transactions-without-fixtures)\n- [**Development**](#development)\n - [Running the tests](#running-the-tests)\n - [Acknowledgements](#acknowledgements)\n - [Copyright](#copyright)\n\n## Motivation\n\nInspired by [Django's built-in support for transactional\ntests](https://jeancochrane.com/blog/django-test-transactions), this plugin \nseeks to provide comprehensive, easy-to-use Pytest fixtures for wrapping tests in\ndatabase transactions for [Flask-SQLAlchemy](http://flask-sqlalchemy.pocoo.org/latest/)\napps. The goal is to make testing stateful Flask-SQLAlchemy applications easier by\nproviding fixtures that permit the developer to **make arbitrary database updates\nwith the confidence that any changes made during a test will roll back** once the test exits.\n\n## Quick examples\n\nUse the [`db_session` fixture](#db_session) to make **database updates that won't persist beyond\nthe body of the test**:\n\n```python\ndef test_a_transaction(db_session):\n row = db_session.query(Table).get(1) \n row.name = 'testing'\n\n db_session.add(row)\n db_session.commit()\n\ndef test_transaction_doesnt_persist(db_session):\n row = db_session.query(Table).get(1) \n assert row.name != 'testing'\n```\n\nThe [`db_engine` fixture](#db_engine) works the same way, but **copies the API of\nSQLAlchemy's [Engine\nobject](http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine)**:\n\n```python\ndef test_a_transaction_using_engine(db_engine):\n with db_engine.begin() as conn:\n row = conn.execute('''UPDATE table SET name = 'testing' WHERE id = 1''')\n\ndef test_transaction_doesnt_persist(db_engine):\n row_name = db_engine.execute('''SELECT name FROM table WHERE id = 1''').fetchone()[0]\n assert row_name != 'testing' \n```\n\nUse [configuration properties](#test-configuration) to\n**mock database connections in an app and enforce nested transactions**,\nallowing any method from the codebase to run inside a test with the assurance\nthat any database changes made will be rolled back at the end of the test:\n\n```ini\n# In setup.cfg\n\n[tool:pytest]\nmocked-sessions=database.db.session\nmocked-engines=database.engine\n```\n\n```python\n# In database.py\n\ndb = flask_sqlalchemy.SQLAlchemy()\nengine = sqlalchemy.create_engine('DATABASE_URI')\n```\n\n```python\n# In models.py\n\nclass Table(db.Model):\n __tablename__ = 'table'\n id = db.Column(db.Integer, primary_key=True)\n name = db.Column(db.String(80))\n\n def set_name(new_name)\n self.name = new_name\n db.session.add(self)\n db.session.commit()\n```\n\n```python\n# In tests/test_set_name.py\n\ndef test_set_name(db_session):\n row = db_session.query(Table).get(1)\n row.set_name('testing')\n assert row.name == 'testing'\n\ndef test_transaction_doesnt_persist(db_session):\n row = db_session.query(Table).get(1) \n assert row.name != 'testing'\n```\n\n# Usage\n\n## Installation\n\n### From PyPi\n\nInstall using pip:\n\n```\npip install pytest-flask-sqlalchemy\n```\n\nOnce installed, pytest will detect the plugin automatically during test collection.\nFor basic background on using third-party plugins with pytest, see the [pytest\ndocumentation](https://docs.pytest.org/en/latest/plugins.html?highlight=plugins).\n\n### Development version\n\nClone the repo from GitHub and switch into the new directory:\n\n```\ngit clone git@github.com:jeancochrane/pytest-flask-sqlalchemy.git\ncd pytest-flask-sqlalchemy\n```\n\nYou can install using pip:\n\n```\npip install .\n```\n\n### Supported backends\n\nSo far, pytest-flask-sqlalchemy has been most extensively tested against\nPostgreSQL 9.6. It should theoretically work with any backend that is supported\nby SQLAlchemy, but Postgres is the only backend that is currently tested by the\ntest suite.\n\nOfficial support for SQLite and MySQL is [planned for a future\nrelease](https://github.com/jeancochrane/pytest-flask-sqlalchemy/issues/3).\nIn the meantime, if you're using one of those backends and you run in to\nproblems, we would greatly appreciate your help! [Open an\nissue](https://github.com/jeancochrane/pytest-flask-sqlalchemy/issues/new) if\nsomething isn't working as you expect.\n\n## Configuration\n\n### Conftest setup\n\nThis plugin assumes that a fixture called `_db` has been\ndefined in the root conftest file for your tests. The `_db` fixture should\nexpose access to a valid [SQLAlchemy `Session` object](http://docs.sqlalchemy.org/en/latest/orm/session_api.html?highlight=session#sqlalchemy.orm.session.Session) that can interact with your database,\nfor example via the [`SQLAlchemy` initialization class](http://flask-sqlalchemy.pocoo.org/2.3/api/#flask_sqlalchemy.SQLAlchemy)\nthat configures Flask-SQLAlchemy.\n\nThe fixtures in this plugin depend on this `_db` fixture to access your\ndatabase and create nested transactions to run tests in. **You must define\nthis fixture in your `conftest.py` file for the plugin to work.**\n\nAn example setup that will produce a valid `_db` fixture could look like this\n(this example comes from the [test setup](./tests/_conftest.py#L25-L61) for this repo):\n\n```python\n@pytest.fixture(scope='session')\ndef database(request):\n '''\n Create a Postgres database for the tests, and drop it when the tests are done.\n '''\n pg_host = DB_OPTS.get(\"host\")\n pg_port = DB_OPTS.get(\"port\")\n pg_user = DB_OPTS.get(\"username\")\n pg_db = DB_OPTS[\"database\"]\n\n init_postgresql_database(pg_user, pg_host, pg_port, pg_db)\n\n @request.addfinalizer\n def drop_database():\n drop_postgresql_database(pg_user, pg_host, pg_port, pg_db, 9.6)\n\n\n@pytest.fixture(scope='session')\ndef app(database):\n '''\n Create a Flask app context for the tests.\n '''\n app = Flask(__name__)\n\n app.config['SQLALCHEMY_DATABASE_URI'] = DB_CONN\n\n return app\n\n\n@pytest.fixture(scope='session')\ndef _db(app):\n '''\n Provide the transactional fixtures with access to the database via a Flask-SQLAlchemy\n database connection.\n '''\n db = SQLAlchemy(app=app)\n\n return db\n```\n\nAlternatively, if you already have a fixture that sets up database access for\nyour tests, you can define `_db` to return that fixture directly:\n\n```python\n@pytest.fixture(scope='session')\ndef database():\n # Set up all your database stuff here\n # ...\n return db\n\n@pytest.fixture(scope='session')\ndef _db(database):\n return database\n```\n\n### Test configuration\n\nThis plugin allows you to configure a few different properties in a \n`setup.cfg` test configuration file in order to handle the specific database connection needs\nof your app. For basic background on setting up pytest configuration files, see\nthe [pytest docs](https://docs.pytest.org/en/latest/customize.html#adding-default-options).\n\nAll three configuration properties ([`mocked-engines`](#mocked-engines),\n[`mocked-sessions`](#mocked-sessions), and [`mocked-sessionmakers`](#mocked-sessionmakers))\nwork by **[patching](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)\none or more specified objects during a test**, replacing them with equivalent objects whose\ndatabase interactions will run inside of a transaction and ultimately be\nrolled back when the test exits. Using these patches, you can call methods from\nyour codebase that alter database state with the knowledge that no changes will persist\nbeyond the body of the test.\n\nThe configured patches are only applied in tests where a transactional fixture\n(either [`db_session`](#db_session) or [`db_engine`](#db_engine)) is included\nin the test function arguments.\n\n#### `mocked-engines`\n\nThe `mocked-engines` property directs the plugin to [patch](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)\nobjects in your codebase, typically SQLAlchemy [Engine](http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine)\ninstances, replacing them with the [`db_engine` fixture](#db_engine) such that\nany database updates performed by the objects get rolled back at the end of \nthe test. \n\nThe value for this property should be formatted as a whitespace-separated list \nof standard Python import paths, like `database.engine`. This property is **optional**.\n\nExample:\n\n```python\n# In database.py\n\nengine = sqlalchemy.create_engine(DATABASE_URI)\n```\n\n```ini\n# In setup.cfg\n\n[tool:pytest]\nmocked-engines=database.engine\n```\n\nTo patch multiple objects at once, separate the paths with a whitespace:\n\n```ini\n# In setup.cfg\n\n[tool:pytest]\nmocked-engines=database.engine database.second_engine\n```\n\n#### `mocked-sessions`\n\nThe `mocked-sessions` property directs the plugin to [patch](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)\nobjects in your codebase, typically SQLAlchemy [Session](http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine)\ninstances, replacing them with the [`db_session`](#db_session) fixture such that\nany database updates performed by the objects get rolled back at the end of \nthe test. \n\nThe value for this property should be formatted as a whitespace-separated list \nof standard Python import paths, like `database.db.session`. This property is **optional**.\n\nExample:\n\n```python\n# In database.py\n\ndb = SQLAlchemy()\n```\n\n```ini\n# In setup.cfg\n\n[tool:pytest]\nmocked-sessions=database.db.session\n```\n\nTo patch multiple objects at once, separate the paths with a whitespace:\n\n```ini\n# In setup.cfg\n\n[tool:pytest]\nmocked-sessions=database.db.session database.second_db.session\n```\n\n#### `mocked-sessionmakers`\n\nThe `mocked-sessionmakers` property directs the plugin to [patch](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)\nobjects in your codebase, typically instances of [SQLAlchemy's `sessionmaker`\nfactory](http://docs.sqlalchemy.org/en/latest/orm/session_api.html?highlight=sessionmaker#sqlalchemy.orm.session.sessionmaker),\nreplacing them with a mocked class that will return the transactional\n[`db_session`](#db_session) fixture. This can be useful if you have\npre-configured instances of sessionmaker objects that you import in the code\nto spin up sessions on the fly.\n\nThe value for this property should be formatted as a whitespace-separated list \nof standard Python import paths, like `database.WorkerSessionmaker`. This property is **optional**.\n\nExample:\n\n```python\n# In database.py\n\nWorkerSessionmaker = sessionmaker()\n```\n\n```ini\n[tool:pytest]\nmocked-sessionmakers=database.WorkerSessionmaker\n```\n\nTo patch multiple objects at once, separate the paths with a whitespace.\n\n```ini\n[tool:pytest]\nmocked-sessionmakers=database.WorkerSessionmaker database.SecondWorkerSessionmaker\n```\n\n### Writing transactional tests\n\nOnce you have your [conftest file set up](#conftest-setup) and you've [overrided the\nnecessary connectables in your test configuration](#test-configuration), you're ready\nto write some transactional tests. Simply import one of the module's [transactional\nfixtures](#fixtures) in your test signature, and the test will be wrapped in a transaction.\n\nNote that by default, **tests are only wrapped in transactions if they import one of\nthe [transactional fixtures](#fixtures) provided by this module.** Tests that do not\nimport the fixture will interact with your database without opening a transaction:\n\n```python\n# This test will be wrapped in a transaction.\ndef transactional_test(db_session):\n ...\n\n# This test **will not** be wrapped in a transaction, since it does not import a\n# transactional fixture.\ndef non_transactional_test():\n ...\n```\n\nThe fixtures provide a way for you to control which tests require transactions and\nwhich don't. This is often useful, since avoiding transaction setup can speed up\ntests that don't interact with your database.\n\nFor more information about the transactional fixtures provided by this module, read on\nto the [fixtures section](#fixtures). For guidance on how to automatically enable\ntransactions without having to specify fixtures, see the section on [enabling transactions\nwithout fixtures](#enabling-transactions-without-fixtures).\n\n## Fixtures\n\nThis plugin provides two fixtures for performing database updates inside nested\ntransactions that get rolled back at the end of a test: [`db_session`](#db_session) and\n[`db_engine`](#db_engine). The fixtures provide similar functionality, but\nwith different APIs.\n\n### `db_session`\n\nThe `db_session` fixture allows you to perform direct updates that will be\nrolled back when the test exits. It exposes the same API as [SQLAlchemy's\n`scoped_session` object](http://docs.sqlalchemy.org/en/latest/orm/contextual.html#sqlalchemy.orm.scoping.scoped_session).\n\nIncluding this fixture as a function argument of a test will activate any mocks that are defined\nby the configuration properties [`mocked-engines`](#mocked-engines), [`mocked-sessions`](#mocked-sessions),\nor [`mocked-sessionmakers`](#mocked-sessionmakers) in the test configuration file for\nthe duration of that test.\n\nExample:\n\n```python\ndef test_a_transaction(db_session):\n row = db_session.query(Table).get(1) \n row.name = 'testing'\n\n db_session.add(row)\n db_session.commit()\n\ndef test_transaction_doesnt_persist(db_session):\n row = db_session.query(Table).get(1) \n assert row.name != 'testing'\n```\n\n### `db_engine`\n\nLike [`db_session`](#db_session), the `db_engine` fixture allows you to perform direct updates\nagainst the test database that will be rolled back when the test exits. It is\nan instance of Python's built-in [`MagicMock`](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock)\nclass, with a spec set to match the API of [SQLAlchemy's\n`Engine`](http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine) object.\n\nOnly a few `Engine` methods are exposed on this fixture:\n\n- `db_engine.begin`: begin a new nested transaction ([API docs](http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine.begin))\n- `db_engine.execute`: execute a raw SQL query ([API docs](http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine.execute)) \n- `db_engine.raw_connection`: return a raw DBAPI connection ([API docs](http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Engine.raw_connection)) \n\nSince `db_engine` is an instance of `MagicMock` with an `Engine` spec, other\nmethods of the `Engine` API can be called, but they will not perform any useful\nwork.\n\nIncluding this fixture as a function argument of a test will activate any mocks that are defined\nby the configuration properties [`mocked-engines`](#mocked-engines), [`mocked-sessions`](#mocked-sessions),\nor [`mocked-sessionmakers`](#mocked-sessionmakers) in the test configuration file for\nthe duration of that test.\n\nExample:\n\n```python\ndef test_a_transaction_using_engine(db_engine):\n with db_engine.begin() as conn:\n row = conn.execute('''UPDATE table SET name = 'testing' WHERE id = 1''')\n\ndef test_transaction_doesnt_persist(db_engine):\n row_name = db_engine.execute('''SELECT name FROM table WHERE id = 1''').fetchone()[0]\n assert row_name != 'testing' \n```\n\n## Enabling transactions without fixtures\n\nIf you know you want to make all of your tests transactional, it can be annoying to have\nto specify one of the [fixtures](#fixtures) in every test signature.\n\nThe best way to automatically enable transactions without having to include an extra fixture\nin every test is to wire up an\n[autouse fixture](https://docs.pytest.org/en/latest/fixture.html#autouse-fixtures-xunit-setup-on-steroids)\nfor your test suite. This can be as simple as:\n\n```python\n# Automatically enable transactions for all tests, without importing any extra fixtures.\n@pytest.fixture(autouse=True)\ndef enable_transactional_tests(db_session):\n pass\n```\n\nIn this configuration, the `enable_transactional_tests` fixture will be automatically used in\nall tests, meaning that `db_session` will also be used. This way, all tests will be wrapped\nin transactions without having to explicitly require either `db_session` or `enable_transactional_tests`.\n\n# Development\n\n## Running the tests\n\nTo run the tests, start by installing a development version of the plugin that\nincludes test dependencies:\n\n```\npip install -e .[tests]\n```\n\nNext, export a [database connection string](http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls)\nthat the tests can use (the database referenced by the string will be created\nduring test setup, so it does not need to exist):\n\n```\nexport TEST_DATABASE_URL=\n```\n\nFinally, run the tests using pytest:\n\n```\npytest\n```\n\n## Acknowledgements\n\nThis plugin was initially developed for testing\n[Dedupe.io](https://dedupe.io), a web app for record linkage and entity\nresolution using machine learning. Dedupe.io is built and maintained\nby [DataMade](https://datamade.us).\n\nThe code is greatly indebted to [Alex Michael](https://github.com/alexmic),\nwhose blog post [\"Delightful testing with pytest and\nFlask-SQLAlchemy\"](http://alexmic.net/flask-sqlalchemy-pytest/) helped\nestablish the basic approach on which this plugin builds.\n\nMany thanks to [Igor Ghisi](https://github.com/igortg/), who donated the PyPi\npackage name. Igor had been working on a similar plugin and proposed combining\nefforts. Thanks to Igor, the plugin name is much stronger.\n\n## Copyright\n\nCopyright (c) 2019 Jean Cochrane and DataMade. Released under the MIT License.\n\nThird-party copyright in this distribution is noted where applicable.\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/jeancochrane/pytest-flask-sqlalchemy",
"keywords": "",
"license": "MIT",
"maintainer": "",
"maintainer_email": "",
"name": "pytest-flask-sqlalchemy",
"package_url": "https://pypi.org/project/pytest-flask-sqlalchemy/",
"platform": "",
"project_url": "https://pypi.org/project/pytest-flask-sqlalchemy/",
"project_urls": {
"Homepage": "https://github.com/jeancochrane/pytest-flask-sqlalchemy"
},
"release_url": "https://pypi.org/project/pytest-flask-sqlalchemy/1.0.2/",
"requires_dist": [
"pytest (>=3.2.1)",
"pytest-mock (>=1.6.2)",
"SQLAlchemy (>=1.2.2)",
"Flask-SQLAlchemy (>=2.3)",
"packaging (>=14.1)",
"pytest-postgresql ; extra == 'tests'"
],
"requires_python": "",
"summary": "A pytest plugin for preserving test isolation in Flask-SQlAlchemy using database transactions.",
"version": "1.0.2"
},
"last_serial": 5093759,
"releases": {
"1.0.0": [
{
"comment_text": "",
"digests": {
"md5": "60292c4427892c985eb84139990374e0",
"sha256": "36a9a7f3db8f50894653e73d0209f3aa5afa97b110c52b2ea61728d2484e1ec1"
},
"downloads": -1,
"filename": "pytest_flask_sqlalchemy-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "60292c4427892c985eb84139990374e0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 9813,
"upload_time": "2018-08-02T01:01:21",
"url": "https://files.pythonhosted.org/packages/63/60/2d8360a81bfaf5fb98f1cad9a92c30f444daac1c2f96b9854b5693629bcd/pytest_flask_sqlalchemy-1.0.0-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "9e98241cc11c3f4d6226bd5cadd70355",
"sha256": "240e9cdf8edafded79045773c68d945a544a4f0b78f7ae9370ce67e8683c6af3"
},
"downloads": -1,
"filename": "pytest-flask-sqlalchemy-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "9e98241cc11c3f4d6226bd5cadd70355",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11370,
"upload_time": "2018-08-02T01:01:22",
"url": "https://files.pythonhosted.org/packages/46/c6/16bee5395d03e41e69a5f811f10ee6c92d4b7aeb39e02d8b440b54d37e29/pytest-flask-sqlalchemy-1.0.0.tar.gz"
}
],
"1.0.1": [
{
"comment_text": "",
"digests": {
"md5": "cf54728bf091a6370fbcf46222fb29fd",
"sha256": "6de3a81cb5616026f565869ed81f015bdcc8e8777da2201ad87ef955a2ba1468"
},
"downloads": -1,
"filename": "pytest_flask_sqlalchemy-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "cf54728bf091a6370fbcf46222fb29fd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 11494,
"upload_time": "2019-03-02T19:03:57",
"url": "https://files.pythonhosted.org/packages/90/a3/50d92b16984fe759e11fea861c177ae32ca5c47dca6de35f591b1835ed88/pytest_flask_sqlalchemy-1.0.1-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "85bd2c0db75d161a9952ece64ead4a12",
"sha256": "ee3c409f213893c33ce891b0416ab0ad050e86103cc24368bf75f5c1b3366a8e"
},
"downloads": -1,
"filename": "pytest-flask-sqlalchemy-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "85bd2c0db75d161a9952ece64ead4a12",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11257,
"upload_time": "2019-03-02T19:03:58",
"url": "https://files.pythonhosted.org/packages/47/e7/840a437f4d18e196f8d69cc8d58547091d5bedac546b4330c87cc57a6c96/pytest-flask-sqlalchemy-1.0.1.tar.gz"
}
],
"1.0.2": [
{
"comment_text": "",
"digests": {
"md5": "ecf3e0ce078c292991785df0307e142f",
"sha256": "19cad31d654c2301dd2dd70d06a62e5dc4ea380500f4b89bbcb3d59a475f0cf6"
},
"downloads": -1,
"filename": "pytest_flask_sqlalchemy-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ecf3e0ce078c292991785df0307e142f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 11659,
"upload_time": "2019-04-04T00:49:34",
"url": "https://files.pythonhosted.org/packages/b2/bc/2c2c3249a1328fc22e7f2c5027f1316f49bf0428c37492b344c4d7c25b24/pytest_flask_sqlalchemy-1.0.2-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "ee2f86c77d061d95ed22c0be302055d4",
"sha256": "34fa0f9a63c3892f54a8d11ab67f907c0e0911ac609e3cff5d518c3af6b897cd"
},
"downloads": -1,
"filename": "pytest-flask-sqlalchemy-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "ee2f86c77d061d95ed22c0be302055d4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11413,
"upload_time": "2019-04-04T00:49:35",
"url": "https://files.pythonhosted.org/packages/a2/19/4c975be16c745db333d7bc7809e0bfb8f22b6ac0daf9880bba24a689029a/pytest-flask-sqlalchemy-1.0.2.tar.gz"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "ecf3e0ce078c292991785df0307e142f",
"sha256": "19cad31d654c2301dd2dd70d06a62e5dc4ea380500f4b89bbcb3d59a475f0cf6"
},
"downloads": -1,
"filename": "pytest_flask_sqlalchemy-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ecf3e0ce078c292991785df0307e142f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 11659,
"upload_time": "2019-04-04T00:49:34",
"url": "https://files.pythonhosted.org/packages/b2/bc/2c2c3249a1328fc22e7f2c5027f1316f49bf0428c37492b344c4d7c25b24/pytest_flask_sqlalchemy-1.0.2-py3-none-any.whl"
},
{
"comment_text": "",
"digests": {
"md5": "ee2f86c77d061d95ed22c0be302055d4",
"sha256": "34fa0f9a63c3892f54a8d11ab67f907c0e0911ac609e3cff5d518c3af6b897cd"
},
"downloads": -1,
"filename": "pytest-flask-sqlalchemy-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "ee2f86c77d061d95ed22c0be302055d4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11413,
"upload_time": "2019-04-04T00:49:35",
"url": "https://files.pythonhosted.org/packages/a2/19/4c975be16c745db333d7bc7809e0bfb8f22b6ac0daf9880bba24a689029a/pytest-flask-sqlalchemy-1.0.2.tar.gz"
}
]
}