{"id":19097242,"url":"https://github.com/lycantropos/hypothesis_sqlalchemy","last_synced_at":"2025-04-30T14:30:08.859Z","repository":{"id":25457089,"uuid":"103796819","full_name":"lycantropos/hypothesis_sqlalchemy","owner":"lycantropos","description":"hypothesis strategies for generating SQLAlchemy objects","archived":false,"fork":false,"pushed_at":"2023-02-04T17:47:24.000Z","size":207,"stargazers_count":29,"open_issues_count":5,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-19T04:41:21.557Z","etag":null,"topics":["hypothesis","quickcheck","sqlalchemy","testing"],"latest_commit_sha":null,"homepage":"","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/lycantropos.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}},"created_at":"2017-09-17T02:15:59.000Z","updated_at":"2025-02-12T23:37:57.000Z","dependencies_parsed_at":"2023-02-18T18:30:29.306Z","dependency_job_id":null,"html_url":"https://github.com/lycantropos/hypothesis_sqlalchemy","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/lycantropos%2Fhypothesis_sqlalchemy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lycantropos%2Fhypothesis_sqlalchemy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lycantropos%2Fhypothesis_sqlalchemy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lycantropos%2Fhypothesis_sqlalchemy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lycantropos","download_url":"https://codeload.github.com/lycantropos/hypothesis_sqlalchemy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251225735,"owners_count":21555319,"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":["hypothesis","quickcheck","sqlalchemy","testing"],"created_at":"2024-11-09T03:39:33.314Z","updated_at":"2025-04-30T14:30:08.829Z","avatar_url":"https://github.com/lycantropos.png","language":"Python","readme":"hypothesis_sqlalchemy\n=====================\n\n[![](https://github.com/lycantropos/hypothesis_sqlalchemy/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/lycantropos/hypothesis_sqlalchemy/actions/workflows/ci.yml \"Github Actions\")\n[![](https://codecov.io/gh/lycantropos/hypothesis_sqlalchemy/branch/master/graph/badge.svg)](https://codecov.io/gh/lycantropos/hypothesis_sqlalchemy \"Codecov\")\n[![](https://img.shields.io/github/license/lycantropos/hypothesis_sqlalchemy.svg)](https://github.com/lycantropos/hypothesis_sqlalchemy/blob/master/LICENSE \"License\")\n[![](https://badge.fury.io/py/hypothesis-sqlalchemy.svg)](https://badge.fury.io/py/hypothesis-sqlalchemy \"PyPI\")\n\nIn what follows `python` is an alias for `python3.7` or `pypy3.7`\nor any later version (`python3.8`, `pypy3.8` and so on).\n\nInstallation\n------------\n\nInstall the latest `pip` \u0026 `setuptools` packages versions\n```bash\npython -m pip install --upgrade pip setuptools\n```\n\n### User\n\nDownload and install the latest stable version from `PyPI` repository\n```bash\npython -m pip install --upgrade hypothesis_sqlalchemy\n```\n\n### Developer\n\nDownload the latest version from `GitHub` repository\n```bash\ngit clone https://github.com/lycantropos/hypothesis_sqlalchemy.git\ncd hypothesis_sqlalchemy\n```\n\nInstall dependencies\n```bash\npython -m pip install -r requirements.txt\n```\n\nInstall\n```bash\npython setup.py install\n```\n\nUsage\n-----\n\nWith setup\n```python\n\u003e\u003e\u003e import warnings\n\u003e\u003e\u003e from hypothesis.errors import NonInteractiveExampleWarning\n\u003e\u003e\u003e # ignore hypothesis warnings caused by `example` method call\n... warnings.filterwarnings('ignore', category=NonInteractiveExampleWarning)\n\n```\nlet's take a look at what can be generated and how.\n\n### Tables\n\nWe can write a strategy that produces tables\n```python\n\u003e\u003e\u003e from hypothesis_sqlalchemy import scheme\n\u003e\u003e\u003e from sqlalchemy.engine.default import DefaultDialect\n\u003e\u003e\u003e dialect = DefaultDialect()\n\u003e\u003e\u003e tables = scheme.tables(dialect,\n...                        min_size=3,\n...                        max_size=10)\n\u003e\u003e\u003e table = tables.example()\n\u003e\u003e\u003e from sqlalchemy.schema import Table\n\u003e\u003e\u003e isinstance(table, Table)\nTrue\n\u003e\u003e\u003e from sqlalchemy.schema import Column\n\u003e\u003e\u003e all(isinstance(column, Column) for column in table.columns)\nTrue\n\u003e\u003e\u003e 3 \u003c= len(table.columns) \u003c= 10\nTrue\n\n```\n\n### Records\n\nSuppose we have a table\n```python\n\u003e\u003e\u003e from sqlalchemy.schema import (Column,\n...                                MetaData,\n...                                Table)\n\u003e\u003e\u003e from sqlalchemy.sql.sqltypes import (Integer,\n...                                      String)\n\u003e\u003e\u003e metadata = MetaData()\n\u003e\u003e\u003e user_table = Table('user', metadata,\n...                    Column('user_id', Integer,\n...                           primary_key=True),\n...                    Column('user_name', String(16),\n...                           nullable=False),\n...                    Column('email_address', String(60)),\n...                    Column('password', String(20),\n...                           nullable=False))\n\n```\nand we can write strategy that\n* produces single records (as `tuple`s)\n    ```python\n    \u003e\u003e\u003e from hypothesis import strategies\n    \u003e\u003e\u003e from hypothesis_sqlalchemy.sample import table_records\n    \u003e\u003e\u003e records = table_records(user_table, \n    ...                         email_address=strategies.emails())\n    \u003e\u003e\u003e record = records.example()\n    \u003e\u003e\u003e isinstance(record, tuple)\n    True\n    \u003e\u003e\u003e len(record) == len(user_table.columns)\n    True\n    \u003e\u003e\u003e all(column.nullable and value is None\n    ...     or isinstance(value, column.type.python_type) \n    ...     for value, column in zip(record, user_table.columns))\n    True\n  \n    ```\n* produces records `list`s (with configurable `list` size bounds)\n    ```python\n    \u003e\u003e\u003e from hypothesis_sqlalchemy.sample import table_records_lists\n    \u003e\u003e\u003e records_lists = table_records_lists(user_table,\n    ...                                     min_size=2,\n    ...                                     max_size=5, \n    ...                                     email_address=strategies.emails())\n    \u003e\u003e\u003e records_list = records_lists.example()\n    \u003e\u003e\u003e isinstance(records_list, list)\n    True\n    \u003e\u003e\u003e 2 \u003c= len(records_list) \u003c= 5\n    True\n    \u003e\u003e\u003e all(isinstance(record, tuple) for record in records_list)\n    True\n    \u003e\u003e\u003e all(len(record) == len(user_table.columns) for record in records_list)\n    True\n\n    ```\n\nDevelopment\n-----------\n\n### Bumping version\n\n#### Preparation\n\nInstall\n[bump2version](https://github.com/c4urself/bump2version#installation).\n\n#### Pre-release\n\nChoose which version number category to bump following [semver\nspecification](http://semver.org/).\n\nTest bumping version\n```bash\nbump2version --dry-run --verbose $CATEGORY\n```\n\nwhere `$CATEGORY` is the target version number category name, possible\nvalues are `patch`/`minor`/`major`.\n\nBump version\n```bash\nbump2version --verbose $CATEGORY\n```\n\nThis will set version to `major.minor.patch-alpha`. \n\n#### Release\n\nTest bumping version\n```bash\nbump2version --dry-run --verbose release\n```\n\nBump version\n```bash\nbump2version --verbose release\n```\n\nThis will set version to `major.minor.patch`.\n\n### Running tests\n\nInstall dependencies\n```bash\npython -m pip install -r requirements-tests.txt\n```\n\nPlain\n```bash\npytest\n```\n\nInside `Docker` container:\n- with `CPython`\n  ```bash\n  docker-compose --file docker-compose.cpython.yml up\n  ```\n- with `PyPy`\n  ```bash\n  docker-compose --file docker-compose.pypy.yml up\n  ```\n\n`Bash` script:\n- with `CPython`\n  ```bash\n  ./run-tests.sh\n  ```\n  or\n  ```bash\n  ./run-tests.sh cpython\n  ```\n\n- with `PyPy`\n  ```bash\n  ./run-tests.sh pypy\n  ```\n\n`PowerShell` script:\n- with `CPython`\n  ```powershell\n  .\\run-tests.ps1\n  ```\n  or\n  ```powershell\n  .\\run-tests.ps1 cpython\n  ```\n- with `PyPy`\n  ```powershell\n  .\\run-tests.ps1 pypy\n  ```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flycantropos%2Fhypothesis_sqlalchemy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flycantropos%2Fhypothesis_sqlalchemy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flycantropos%2Fhypothesis_sqlalchemy/lists"}