{"id":26509647,"url":"https://github.com/paulophagula/ezrecords","last_synced_at":"2025-03-21T01:20:01.444Z","repository":{"id":57427945,"uuid":"78162405","full_name":"PauloPhagula/ezrecords","owner":"PauloPhagula","description":":vhs: ezrecords - SQL for Humans™ Enhanced","archived":false,"fork":false,"pushed_at":"2024-12-02T05:46:04.000Z","size":432,"stargazers_count":3,"open_issues_count":7,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-17T08:49:29.980Z","etag":null,"topics":["ezsql","for-humans","mysql","postgres","python","records","sql","wpdb"],"latest_commit_sha":null,"homepage":"https://paulophagula.github.io/ezrecords/","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/PauloPhagula.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","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-01-06T01:25:50.000Z","updated_at":"2024-10-08T15:16:35.000Z","dependencies_parsed_at":"2023-01-30T19:01:13.713Z","dependency_job_id":null,"html_url":"https://github.com/PauloPhagula/ezrecords","commit_stats":null,"previous_names":["dareenzo/ezrecords"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PauloPhagula%2Fezrecords","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PauloPhagula%2Fezrecords/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PauloPhagula%2Fezrecords/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PauloPhagula%2Fezrecords/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PauloPhagula","download_url":"https://codeload.github.com/PauloPhagula/ezrecords/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244717519,"owners_count":20498310,"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":["ezsql","for-humans","mysql","postgres","python","records","sql","wpdb"],"created_at":"2025-03-21T01:20:00.611Z","updated_at":"2025-03-21T01:20:01.437Z","avatar_url":"https://github.com/PauloPhagula.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"ezrecords: SQL for Humans™ Enhanced\n====================================\n\n\n.. image:: https://img.shields.io/pypi/v/ezrecords.svg\n    :target: https://pypi.org/project/ezrecords\n    :alt: PyPI\n\n.. image:: https://github.com/PauloPhagula/ezrecords/actions/workflows/ci.yml/badge.svg\n    :target: https://github.com/PauloPhagula/ezrecords/actions/workflows/ci.yml\n    :alt: CI\n\n.. image:: https://coveralls.io/repos/github/PauloPhagula/ezrecords/badge.svg?branch=master\n    :target: https://coveralls.io/github/PauloPhagula/ezrecords?branch=master\n    :alt: Coverage\n\n.. image:: https://img.shields.io/github/license/PauloPhagula/ezrecords.svg\n    :target: https://github.com/PauloPhagula/ezrecords/blob/master/LICENSE\n    :alt: License\n\n.. _LICENSE: http://www.github.com/PauloPhagula/ezrecords/blob/master/LICENSE\n.. _records: https://github.com/kennethreitz/records\n.. _ezsql: https://github.com/ezSQL/ezSQL\n.. _wpdb: https://codex.wordpress.org/Class_Reference/wpdb\n.. _SQLAlchemy: http://www.sqlalchemy.org\n\n\n**ezrecords is a very simple, but powerful, library for making raw SQL\nqueries to most relational databases.**\n\nezrecords = Kenneth Reitz's `records`_ + Justin Vincent's `ezsql`_ + WordPress' `wpdb`_ - `SQLAlchemy`_.\n\nJust write SQL. No bells, no whistles. This common task can be\nsurprisingly difficult with the standard tools available.\nThis library strives to make this workflow as simple as possible,\nwhile providing an elegant interface to work with your query results.\n\n*Database support includes SQLite, Postgres, and MySQL (drivers not included).*\n\nWhy?\n----\n\n- `records`_ is awesome\n- `ezsql`_ and `wpdb`_ have very nice API, so it makes for an easy transition\n  from PHP to Python\n- Our love for crafting well written and performant SQL queries is not questionable,\n  but I think a few helpers for some basic DML and recurring queries would help\n- *\"The ORM takes two brilliant ideas and incapacitates them both.\"*,\n  said a very wise man. So, as long as possible I want to keep away from\n  SQLAlchemy or the like.\n\nUsage\n------\n\nAPI\n~~~\n\n.. code:: Python\n\n    import logging\n    from ezrecords.mysqldb import MySQLDb\n\n    logger = logging.getLogger()\n\n    # connect\n    db = MySQLDb(db_url=\"mysql://root:passwd@127.0.0.1:3306/test\", logger=logger) # logger is optional\n\n    # enable debugging - optional\n    db.save_queries = True  # save queries and execution time\n    db.show_sql = True  # show SQL code being executed. logger above is required for logging to work\n    db.show_errors = True  # show errors\n\n    create_user_table = \"\"\"\n    CREATE TABLE test_user (\n        id INT AUTO_INCREMENT NOT NULL,\n        username varchar(255) UNIQUE,\n        password varchar(255),\n        created_at TIMESTAMP,\n        created_at_gmt TIMESTAMP,\n        PRIMARY KEY(id)\n    )\n    \"\"\"\n    db.query(create_table) # run generic SQL\n\n    create_numbers_table = \"\"\"\n    DROP TABLE IF EXISTS numbers;\n    CREATE TABLE numbers(\n        ints int,\n        floats float\n    );\n    \"\"\"\n    db.query(create_table_sql)\n\n    insert_numbers_sql = \"INSERT INTO numbers (ints, floats) VALUES (%d, %f)\" # DB API only accepts %s, so we replace %d and %f by %s internally\n    db.query(insert_numbers_sql, 3, 3.14) # run generic queries with params\n\n    # insert records\n    db.insert('test_user', username='scott', password='tiger', created_at=datetime.datetime.now())\n    db.insert('test_user', {'username': 'JONES', 'password': 'STEEL'})\n\n    # bulk_insert records\n    db.bulk_insert('test_user', ('username', 'password'), [('scott', 'tiger'), ('JONES', 'STEEL')])\n\n    # Update records\n    db.update('test_user', {'password': 'shepard'}, {'username': 'scott'})\n\n    # Delete records\n    db.delete('test_user', {'username': None}) # None is converted to NULL\n\n    # Sanitize query\n    db.prepare(\"\"\"INSERT INTO postmeta (post_id, meta_key, meta_value) VALUES ( '%d', \"%s\", %%s )')\"\"\", 10, \"Harriet's Adages\", \"WordPress' database interface is like Sunday Morning: Easy.\")\n\n    # Call stored procedures\n    db.call_procedure('adds', 1, 2)\n\n    # Get single variable/value\n    db.get_var('SELECT version()')\n\n    # Get specific row from many results\n    db.get_row('SELECT * FROM test_user', row_offset=1) # if offset not given the first row is returned\n\n    # Get specific column from many results\n    db.get_col('SELECT username, password FROM test_user', column_offset='password')  # offset can be numeric too\n\n    # Get results in specific format\n    db.get_results('SELECT username, password FROM test_user', 'json')\n    # Get last inserted ID from AUTO_INCREMENT/SERIAL fields\n    db.insert('test_user', username='scott', password='tiger', created_at=datetime.datetime.now())\n    db.last_insert_id\n\n    # Get number of affected rows from previus query\n    db.delete('test_user')\n    db.affected_rows\n\n    # Switch to another database\n    db.use('information_schema')\n\n    # Check query timing\n    # execute long running query\n    db.last_query_elapsed_time\n\n    # Transactions\n    # ---\n    db.begin_transaction()\n    db.commit() # or db.rollback()\n\n    # Data export\n    rows = db.query('SELECT * FROM table')\n    rows.dataset\n    rows.export('csv') # yaml, json, xls, xlsx\n\n    # Goodies\n    db.db_version() # get server version\n    db.exists('table') # check if table exists\n    db.get_table_names() # get list of tables in database\n    db.flush() # clear cache results\n\n\nCLI\n~~~\n\nAs an added bonus, a records command-line tool is automatically included. Here's a screenshot of the usage information:\n\n.. image:: artwork/cli.png\n    :alt: CLI\n\nHere's some usage example\n\n.. code:: bash\n\n    ezrecords -h\n    ezrecords \"SELECT version() AS version\" \"json\" --url=\"mysql://root:passwd@127.0.0.1:3306/test\"\n    ezrecords \"SELECT version() AS version\" \"json\" --url=\"postgres://postgres:passwd@127.0.0.1:5432/test\"\n    ezrecords \"SELECT sqlite_version() AS version\" \"json\" --url=\"sqlite:///:memory:\"\n\nInstallation\n--------------------\n\n``pip install ezrecords``\n\nezrecords runs with **Python 2.7 and 3.5**.\n\nDocumentation Generation\n------------------------\n\n.. code-block:: sh\n\n    # edit documentation in _docs\n    cd _docs\n    make singlehtml\n    cd ..\n    cp -fR _docs/_build/singlehtml/* docs/\n\n\nCopyright \u0026 License\n--------------------\n\nCode and documentation are available according to the MIT License.\n\nSee the `LICENSE`_ file for details.\n\n\nThank you\n----------\nThanks for checking this library out! I hope you find it useful.\n\nOf course, there's always room for improvement. Feel free to\n`open an issue \u003chttps://github.com/PauloPhagula/ezrecords/issues\u003e`_\nso we can make **ezrecords** better, faster, and stronger.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulophagula%2Fezrecords","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulophagula%2Fezrecords","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulophagula%2Fezrecords/lists"}