{"id":18437098,"url":"https://github.com/mfussenegger/cr8","last_synced_at":"2025-04-05T06:08:25.492Z","repository":{"id":44550248,"uuid":"41117430","full_name":"mfussenegger/cr8","owner":"mfussenegger","description":"CLI collection of utilities for working with CrateDB or PostgreSQL. Benchmark queries, insert data.","archived":false,"fork":false,"pushed_at":"2024-10-24T09:01:31.000Z","size":515,"stargazers_count":40,"open_issues_count":4,"forks_count":16,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-29T05:07:31.998Z","etag":null,"topics":["cli","cockroachdb","crate","cratedb","database-testing","postgres","postgresql","python","python-3"],"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/mfussenegger.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["mfussenegger"]}},"created_at":"2015-08-20T20:29:48.000Z","updated_at":"2024-11-28T15:52:03.000Z","dependencies_parsed_at":"2023-11-11T11:25:32.294Z","dependency_job_id":"7e542bb8-5324-40ba-abd7-4a18e3e7ffc4","html_url":"https://github.com/mfussenegger/cr8","commit_stats":{"total_commits":426,"total_committers":17,"mean_commits":"25.058823529411764","dds":0.096244131455399,"last_synced_commit":"3729a35ce44c0565058da55a03d72e3157262d0c"},"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfussenegger%2Fcr8","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfussenegger%2Fcr8/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfussenegger%2Fcr8/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfussenegger%2Fcr8/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mfussenegger","download_url":"https://codeload.github.com/mfussenegger/cr8/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294539,"owners_count":20915340,"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":["cli","cockroachdb","crate","cratedb","database-testing","postgres","postgresql","python","python-3"],"created_at":"2024-11-06T06:13:40.196Z","updated_at":"2025-04-05T06:08:25.472Z","avatar_url":"https://github.com/mfussenegger.png","language":"Python","readme":"===\ncr8\n===\n\n.. image:: https://github.com/mfussenegger/cr8/workflows/test%20\u0026%20publish/badge.svg\n    :target: https://github.com/mfussenegger/cr8/actions\n    :alt: github actions\n\n.. image:: https://img.shields.io/pypi/wheel/cr8.svg\n    :target: https://pypi.python.org/pypi/cr8/\n    :alt: Wheel\n\n.. image:: https://img.shields.io/pypi/v/cr8.svg\n   :target: https://pypi.python.org/pypi/cr8/\n   :alt: PyPI Version\n\n.. image:: https://img.shields.io/pypi/pyversions/cr8.svg\n   :target: https://pypi.python.org/pypi/cr8/\n   :alt: Python Version\n\nA collection of command line tools for `Crate\n\u003chttps://github.com/crate/crate\u003e`_ developers (and maybe users as well).\n\nTOC\n====\n\n- `Why cr8? 🤔`_\n- `Install 💾`_\n- `Usage`_\n    - `Shell completion`_\n- `Sub-commands`_\n    - `timeit 🕐`_\n    - `insert-fake-data`_\n    - `insert-json`_\n    - `insert-from-sql`_\n    - `run-spec`_\n    - `run-crate`_\n        - `Script reproduction`_\n        - `Find regressions`_\n        - `Profiling`_\n        - `Creating a CrateDB cluster`_\n    - `run-track`_\n    - `reindex`_\n- `Protocols`_\n- `Development ☢`_\n\n\nWhy cr8? 🤔\n===========\n\n1. To quickly produce sample data. Often if someone reports an issue sample\n   data is required to be able to reproduce it.\n   `insert-fake-data`_ and `insert-json`_ address this problem.\n\n2. To benchmark queries \u0026 compare runtime across Crate versions.  `timeit 🕐`_,\n   `run-spec`_ and `run-track`_ can be used to get runtime statistics of\n   queries.\n   These tools focus on response latencies. Being able to benchmark throughput\n   is NOT a goal of cr8. Similarly, being able to simulate real-world use\n   cases is also NOT a goal of cr8.\n\n\n\n.. note::\n\n    Although most commands output text by default. Most take a ``--output-fmt\n    json`` argument to output JSON.\n    This is useful if used together with `jq`_ to post-process the output\n\n\nInstall 💾\n==========\n\nPython \u003e= 3.7 is required to use the command line tools.\n\nInstall them using `pip \u003chttps://pip.pypa.io/en/stable/\u003e`_::\n\n    python3 -m venv venv\n    venv/bin/python -m pip install cr8\n\nThis will install ``cr8`` into ``venv/bin``\nAn alternative is to download a single ``zipapp`` file from the `releases page\n\u003chttps://github.com/mfussenegger/cr8/releases\u003e`_.\n\n\nUsage\n=====\n\nThe main binary is called ``cr8`` which contains a couple of sub-commands.\n\nUse ``cr8 -h`` or ``cr8 \u003csubcommand\u003e -h`` to get a more detailed usage\ndescription.\n\nThe included sub-commands are described in more detail below:\n\n**Tip**:\n\nAny `\u003csubcommand\u003e` with ``--hosts`` argument supports password authentication\nlike this::\n\n    cr8 \u003csubcommand\u003e --hosts http://username:password@localhost:4200 \u003cremaining args\u003e\n\n\nShell completion\n----------------\n\n``cr8`` supports command completion in both ``bash`` and ``zsh`` via `argcomplete`_.\n\n- Install ``argcomplete``\n- Run ``activate-global-python-argcomplete``\n\nMake sure you're using the ``argcomplete`` \u003e 3.0.\nIn older versions of ``argcomplete`` it would be necessary to use the\n``bashcompinit`` compatibility layer in ``zsh`` and register the application\nvia ``eval \"$(register-python-argcomplete cr8)\"``. See the upstream\ndocumentation for details.\n\n\nSub-commands\n============\n\ntimeit 🕐\n---------\n\nA tool that can be used to measure the runtime of a given SQL statement on a\ncluster::\n\n    \u003e\u003e\u003e echo \"select name from sys.cluster\" | cr8 timeit --hosts localhost:4200\n    Runtime (in ms):\n        mean:    ... ± ...\n        min/max: ... → ...\n    Percentile:\n        50:   ... ± ... (stdev)\n        95:   ...\n        99.9: ...\n\n\ninsert-fake-data\n----------------\n\nA tool that can be used to fill a table with random data. The script will\ngenerate the records using `faker \u003chttps://github.com/joke2k/faker\u003e`_.\n\nFor example given the table as follows::\n\n    create table x.demo (\n        id int,\n        name text,\n        country text\n    );\n\nThe following command can be used to insert 1000 records::\n\n    \u003e\u003e\u003e cr8 insert-fake-data --hosts localhost:4200 --table x.demo --num-records 200\n    Found schema:\n    {\n        \"country\": \"text\",\n        \"id\": \"integer\",\n        \"name\": \"text\"\n    }\n    Using insert statement:\n    insert into \"x\".\"demo\" (\"id\", \"name\", \"country\") values ($1, $2, $3)\n    Will make 1 requests with a bulk size of 200\n    Generating fake data and executing inserts\n    \u003cBLANKLINE\u003e\n\nIt will automatically read the schema from the table and map the columns to\nfaker `providers\n\u003chttps://faker.readthedocs.io/en/latest/providers.html\u003e`_ and insert the\ngive number of records.\n\n(Currently only top-level columns are supported)\n\nAn alternative way to generate random records is `mkjson\n\u003chttps://github.com/mfussenegger/mkjson\u003e`_ which can be used together with\n``insert-json``.\n\ninsert-json\n-----------\n\n``insert-json`` can be used to insert records from a JSON file::\n\n    \u003e\u003e\u003e cat tests/demo.json | cr8 insert-json --table x.demo --hosts localhost:4200\n    Executing inserts: bulk_size=1000 concurrency=25\n    Runtime (in ms):\n        mean:    ... ± 0.000\n\nOr simply print the insert statement generated from a JSON string::\n\n    \u003e\u003e\u003e echo '{\"name\": \"Arthur\"}' | cr8 insert-json --table mytable\n    ('insert into mytable (\"name\") values ($1)', ['Arthur'])\n    ...\n\ninsert-from-sql\n---------------\n\nCopies data from one CrateDB cluster or PostgreSQL server to another.\n\n::\n\n    \u003e\u003e\u003e cr8 insert-from-sql \\\n    ...   --src-uri \"postgresql://crate@localhost:5432/doc\" \\\n    ...   --query \"SELECT name FROM x.demo\" \\\n    ...   --hosts localhost:4200 \\\n    ...   --table y.demo \\\n    INSERT INTO y.demo (\"name\") VALUES ($1)\n    Runtime (in ms):\n    ...\n\n\nThe ``concurrency`` option of the command only affects the number of concurrent\nwrite operations that will be made. There will always be a single read\noperation, so copy operations may be bound by the read performance.\n\n\nrun-spec\n--------\n\nA tool to run benchmarks against a cluster and store the result in another\ncluster. The benchmark itself is defined in a spec file which defines `setup`,\n`benchmark` and `teardown` instructions.\n\nThe instructions itself are just SQL statements (or files containing SQL\nstatements).\n\nIn the `specs` folder is an example spec file.\n\nUsage::\n\n    \u003e\u003e\u003e cr8 run-spec specs/sample.toml localhost:4200 -r localhost:4200\n    # Running setUp\n    # Running benchmark\n    \u003cBLANKLINE\u003e\n    ## Running Query:\n       Name: count countries\n       Statement: select count(*) from countries\n       Concurrency: 2\n       Duration: 1\n    Runtime (in ms):\n        mean:    ... ± ...\n        min/max: ... → ...\n    Percentile:\n        50:   ... ± ... (stdev)\n        95:   ...\n        99.9: ...\n    ...\n    ## Skipping (Version ...\n       Statement: ...\n    # Running tearDown\n    \u003cBLANKLINE\u003e\n\n`-r` is optional and can be used to save the benchmark result into a cluster.\nA table named `benchmarks` will be created if it doesn't exist.\n\nWriting spec files in python is also supported::\n\n    \u003e\u003e\u003e cr8 run-spec specs/sample.py localhost:4200\n    # Running setUp\n    # Running benchmark\n    ...\n\nrun-crate\n---------\n\nLaunch a Crate instance::\n\n    \u003e cr8 run-crate 0.55.0\n\nThis requires Java 8.\n\n``run-crate`` supports chaining of additional commands using ``--``. Under the\ncontext of ``run-crate`` any host urls can be formatted using the\n``{node.http_url}`` format string::\n\n    \u003e\u003e\u003e cr8 run-crate latest-stable -- timeit -s \"select 1\" --hosts '{node.http_url}'\n     # run-crate\n    ===========\n    \u003cBLANKLINE\u003e\n    ...\n    Starting Crate process\n    CrateDB launching:\n        PID: ...\n        Logs: ...\n        Data: ...\n    \u003cBLANKLINE\u003e\n    ...\n    Cluster ready to process requests\n    \u003cBLANKLINE\u003e\n    \u003cBLANKLINE\u003e\n    # timeit\n    ========\n    \u003cBLANKLINE\u003e\n    \u003cBLANKLINE\u003e\n    \u003cBLANKLINE\u003e\n    \u003cBLANKLINE\u003e\n\nIn the above example ``timeit`` is a ``cr8`` specific sub-command. But it's\nalso possible to use arbitrary commands by prefixing them with ``@``::\n\n    cr8 run-crate latest-nightly -- @http '{node.http_url}'\n\n\nScript reproduction\n~~~~~~~~~~~~~~~~~~~\n\nOne common use of this feature is to quickly reproduce bug reports::\n\n    cr8 run-crate latest-nightly -- @crash --hosts {node.http_url} \u003c\u003cEOF\n        create table mytable (x int);\n        insert into mytable (x) values (1);\n        refresh mytable;\n        ...\n    EOF\n\n\nFind regressions\n~~~~~~~~~~~~~~~~\n\nAnother use case is to use ``run-crate`` in combination with ``run-spec`` and\n``git bisect``::\n\n    git bisect run cr8 run-crate path/to/crate/src \\\n        -- run-spec path/to/spec.toml '{node.http_url}' --fail-if '{runtime_stats.mean} \u003e 15'\n\nThis could also be combined with `timeout\n\u003chttps://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html#timeout-invocation\u003e`_.\n\n\nProfiling\n~~~~~~~~~\n\nThis can also be used in combination with the Java flight recorder to do\nprofiling::\n\n    cr8 run-crate latest-nightly \\\n        -e CRATE_HEAP_SIZE=4g \\\n        -e CRATE_JAVA_OPTS=\"-Dcrate.signal_handler.disabled=true -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:+UnlockCommercialFeatures -XX:+FlightRecorder\" \\\n        -s discovery.type=single-node \\\n        -- run-spec path/to/specs/example.toml {node.http_url} --action setup \\\n        -- @jcmd {node.process.pid} JFR.start duration=60s filename=myrecording.jfr \\\n        -- run-spec path/to/specs/example.toml {node.http_url} --action queries \\\n        -- @jcmd {node.process.pid} JFR.stop\n\n\nCreating a CrateDB cluster\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``cr8`` doesn't contain a dedicated command to spawn a CrateDB cluster. But you\ncan run ``cr8 run-crate \u003cversion\u003e -s cluster.name=\u003cname\u003e`` to launch multiple\nnodes. If the cluster name matches, it will form a cluster.\n\n\nrun-track\n---------\n\nA tool to run ``.toml`` track files.\nA track is a matrix definition of node version, configurations and spec files.\n\nFor each version and configuration a Crate node will be launched and all specs\nwill be executed::\n\n    \u003e\u003e\u003e cr8 run-track tracks/sample.toml\n    # Version:  latest-testing\n    ## Starting Crate latest-testing, configuration: default.toml\n    ### Running spec file:  sample.toml\n    # Running setUp\n    # Running benchmark\n    ...\n\n\nreindex\n-------\n\nA command to re-index all tables on a cluster which have been created in the\nprevious major versions. So if you're running a 3.x CrateDB cluster, all tables\nfrom 2.x would be re-created::\n\n   \u003e\u003e\u003e cr8 reindex --help\n   usage: cr8 reindex [-h] --hosts HOSTS\n   ...\n\n\nProtocols\n=========\n\n``cr8`` supports using ``HTTP`` or the ``postgres`` protocol.\n\nNote that using the postgres protocol will cause ``cr8`` to measure the\nround-trip time instead of the service time. So measurements will be different.\n\nTo use the ``postgres`` protocol, the ``asyncpg`` scheme must be used inside hosts URIs:\n\n::\n\n\n    \u003e\u003e\u003e echo \"select 1\" | cr8 timeit --hosts asyncpg://localhost:5432\n    Runtime (in ms):\n    ...\n\n\nDevelopment ☢\n==============\n\nTo get a sandboxed environment with all dependencies installed use ``venv``::\n\n    python -m venv .venv\n    source .venv/bin/activate\n\nInstall the ``cr8`` package using pip::\n\n    python -m pip install -e .\n\nRun ``cr8``::\n\n    cr8 -h\n\nTests are run with ``python -m unittest``\n\n.. _jq: https://stedolan.github.io/jq/\n.. _argcomplete: https://kislyuk.github.io/argcomplete/\n","funding_links":["https://github.com/sponsors/mfussenegger"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfussenegger%2Fcr8","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmfussenegger%2Fcr8","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfussenegger%2Fcr8/lists"}