{"id":16543127,"url":"https://github.com/codemation/pyql","last_synced_at":"2025-03-04T07:13:59.266Z","repository":{"id":62582793,"uuid":"194922896","full_name":"codemation/pyql","owner":"codemation","description":"Library for managing data access to data-bases","archived":false,"fork":false,"pushed_at":"2020-07-30T18:52:02.000Z","size":145,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-14T11:16:24.888Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codemation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-02T19:26:56.000Z","updated_at":"2020-07-30T18:52:04.000Z","dependencies_parsed_at":"2022-11-03T22:01:40.630Z","dependency_job_id":null,"html_url":"https://github.com/codemation/pyql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Fpyql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Fpyql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Fpyql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codemation%2Fpyql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codemation","download_url":"https://codeload.github.com/codemation/pyql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241801257,"owners_count":20022390,"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":[],"created_at":"2024-10-11T18:59:25.200Z","updated_at":"2025-03-04T07:13:59.234Z","avatar_url":"https://github.com/codemation.png","language":"Python","readme":"# pyql\n\nA simple ORM(Object-relational mapping) for accessing, inserting, updating, deleting data within RBDMS tables using python\n\n### Instalation\n\n    $ python3 -m venv env\n\n    $ source my-project/bin/activate\n\nInstall with PIP\n\n     (env)$ pip install pyql-db   \n\nDownload \u0026 install Library from Github:\n\n    (env)$ git clone https://github.com/codemation/pyql.git\n\nUse install script to install the pyql into the activated environment libraries\n\n    (env)$ cd pyql; sudo ./install.py install\n\n### Compatable Databases - Currently\n\n- mysql\n- sqlite\n\n## Getting Started \n\n### DB connection\n\n        import sqlite3\n        from pyql import data\n\n        db = data.Database(\n            sqlite3.connect, \n            database=\"testdb\"\n            )\n    \n        from pyql import data\n        import mysql.connector\n\n        db = data.Database(\n            mysql.connector.connect,\n            database='mysql_database',\n            user='mysqluser',\n            password='my-secret-pw',\n            host='localhost',\n            type='mysql'\n            )\nExisting tables schemas within databases are loaded when database object is instantiated and ready for use immedielty.\n\n### Table Create\nRequires List of at least 2 item tuples, max 3\n\n('column_name', type, 'modifiers')\n\n- column_name - str - database column name exclusions apply\n- types: str, int, float, byte, bool, None # JSON dumpable dicts fall under str types\n- modifiers: NOT NULL, UNIQUE, AUTO_INCREMENT\n\nNote Some differences may apply for column options i.e AUTOINCREMENT(sqlite) vs AUTO_INCREMENT(mysql) - \nSee DB documentation for reference.\n\nNote: Unique constraints are not validated by pyql but at db, so if modifier is supported it will be added when table is created.\n\n    # Table Create    \n    db.create_table(\n        'stocks', \n        [    \n            ('order_num', int, 'AUTO_INCREMENT'),\n            ('date', str),\n            ('trans', str),\n            ('symbol', str),\n            ('qty', float),\n            ('price', str)\n        ], \n        'order_num' # Primary Key \n    )\n    \n    mysql\u003e describe stocks;\n    +-----------+---------+------+-----+---------+----------------+\n    | Field     | Type    | Null | Key | Default | Extra          |\n    +-----------+---------+------+-----+---------+----------------+\n    | order_num | int(11) | NO   | PRI | NULL    | auto_increment |\n    | date      | text    | YES  |     | NULL    |                |\n    | trans     | text    | YES  |     | NULL    |                |\n    | condition | text    | YES  |     | NULL    |                |\n    | symbol    | text    | YES  |     | NULL    |                |\n    | qty       | double  | YES  |     | NULL    |                |\n    | price     | text    | YES  |     | NULL    |                |\n    +-----------+---------+------+-----+---------+----------------+\n    6 rows in set (0.00 sec)\n\n#### Creating Tables with Foreign Keys\n\n    db.create_table(\n        'departments', \n        [    \n            ('id', int, 'UNIQUE'),\n            ('name', str)\n\n        ], \n        'id' # Primary Key \n    )\n\n    db.create_table(\n        'positions', \n        [    \n            ('id', int, 'UNIQUE'),\n            ('name', str),\n            ('department_id', int)\n        ], \n        'id', # Primary Key\n        foreign_keys={\n            'department_id': {\n                    'table': 'departments', \n                    'ref': 'id',\n                    'mods': 'ON UPDATE CASCADE ON DELETE CASCADE'\n            }\n        }\n    )\n\n    db.create_table(\n        'employees', \n        [    \n            ('id', int, 'UNIQUE'),\n            ('name', str),\n            ('position_id', int)\n        ], \n        'id', # Primary Key\n        foreign_keys={\n            'position_id': {\n                    'table': 'positions', \n                    'ref': 'id',\n                    'mods': 'ON UPDATE CASCADE ON DELETE CASCADE'\n            }\n        }\n    )\n\n    \n### Insert Data\nRequires key-value pairs - may be input using dict or the following\n\nUn-packing\n\n    # Note order_num is not required as auto_increment was specified\n    trade = {'date': '2006-01-05', 'trans': 'BUY', 'symbol': 'RHAT', 'qty': 100.0, 'price': 35.14}\n    db.tables['stocks'].insert(\n        **trade\n    )\n\n    query:\n        INSERT INTO \n            stocks (date, trans, symbol, qty, price) \n            VALUES (\"2006-01-05\", \"BUY\", \"RHAT\", 100, 35.14)\n\nIn-Line\n\n    # Note order_num is not required as auto_increment was specified\n    db.tables['stocks'].insert(\n        date='2006-01-05', \n        trans='BUY',\n        symbol='RHAT',\n        qty=200.0,\n        price=65.14\n    )\n\n    query:\n        INSERT INTO stocks (date, trans, symbol, qty, price) VALUES (\"2006-01-05\", \"BUY\", \"RHAT\", 200, 65.14)\n\n#### Inserting Special Data \n- Columns of type string can hold JSON dumpable python dictionaries as JSON strings and are automatically converted back into dicts when read. \n- Nested Dicts are also Ok, but all items should be JSON compatible data types\n\n\n        tx_data = {\n            'type': 'BUY', \n            'condition': {\n                        'limit': '36.00', \n                        'time': 'end_of_trading_day'\n            }\n        }\n\n        trade = {\n            'order_num': 1, 'date': '2006-01-05', \n            'trans': tx_data, # \n            'symbol': 'RHAT', \n            'qty': 100, 'price': 35.14, 'after_hours': True\n        }\n\n        db.tables['stocks'].insert(**trade)\n        query:\n            INSERT INTO \n                stocks (order_num, date, trans, symbol, qty, price, after_hours) \n                VALUES (1, \"2006-01-05\", '{\"type\": \"BUY\", \"condition\": {\"limit\": \"36.00\", \"time\": \"end_of_trading_day\"}}', \"RHAT\", 100, 35.14, True)\n        result:\n            In:\n                db.tables['stocks'][1]['trans']['condition']\n            Out: #\n                {'limit': '36.00', 'time': 'end_of_trading_day'}\n\n        \n### Select Data\n#### Basic Usage:\n\nAll Rows \u0026 Columns in table\n\n    db.tables['employees'].select('*')\n\nAll Rows \u0026 Specific Columns \n\n    db.tables['employees'].select(\n        'id', \n        'name', \n        'position_id'\n    )\n\nAll Rows \u0026 Specific Columns with Matching Values\n\n    db.tables['employees'].select(\n        'id', \n        'name', \n        'position_id', \n        where={'id': 1000}\n    )\n\nAll Rows \u0026 Specific Columns with Multple Matching Values\n\n    db.tables['employees'].select(\n        'id', \n        'name', \n        'position_id', \n        where={\n            'id': 1000, \n            'name': 'Frank Franklin'\n            }\n        )\n\n#### Advanced Usage:\n\nAll Rows \u0026 Columns from employees, Combining ALL Rows \u0026 Columns of table positions (if foreign keys match)\n\n    # Basic Join\n    db.tables['employees'].select(\n        '*', \n        join='positions'\n    )\n    query:\n        SELECT * FROM employees JOIN positions ON employees.position_id = positions.id\n    output:\n        [{\n            'employees.id': 1000, 'employees.name': 'Frank Franklin', \n            'employees.position_id': 100101, 'positions.name': 'Director', \n            'positions.department_id': 1001},\n            ...\n        ]\nAll Rows \u0026 Specific Columns from employees, Combining All Rows \u0026 Specific Columns of table positions (if foreign keys match)\n\n    # Basic Join \n    db.tables['employees'].select(\n        'employees.name', \n        'positions.name', \n        join='positions'\n    )\n    query:\n        SELECT \n            employees.name,\n            positions.name \n        FROM \n            employees \n        JOIN \n            positions \n        ON \n            employees.position_id = positions.id\n    output:\n        [\n            {'employees.name': 'Frank Franklin', 'positions.name': 'Director'}, \n            {'employees.name': 'Eli Doe', 'positions.name': 'Manager'},\n            ...\n        ]\n\nAll Rows \u0026 Specific Columns from employees, Combining All Rows \u0026 Specific Columns of table positions (if foreign keys match) with matching 'position.name' value\n\n    # Basic Join with conditions\n    db.tables['employees'].select(\n        'employees.name', \n        'positions.name', \n        join='positions', # Possible due to foreign key relationship \n        where={\n            'positions.name': 'Director'\n            }\n        )\n    query:\n        SELECT \n            employees.name,\n            positions.name \n        FROM \n            employees \n        JOIN positions ON \n            employees.position_id = positions.id \n        WHERE positions.name='Director'\n    output:\n        [\n            {'employees.name': 'Frank Franklin', 'positions.name': 'Director'}, \n            {'employees.name': 'Elly Doe', 'positions.name': 'Director'},\n            ..\n        ]\n\nAll Rows \u0026 Specific Columns from employees, Combining Specific Rows \u0026 Specific Columns of tables positions \u0026 departments\n\nNote: join='x_table' will only work if the calling table has a f-key reference to table 'x_table'\n\n    # Multi-table Join with conditions\n    db.tables['employees'].select(\n        'employees.name', \n        'positions.name', \n        'departments.name', \n        join={\n            'positions': {'employees.position_id': 'positions.id'}, \n            'departments': {'positions.department_id': 'departments.id'}\n        }, \n        where={'positions.name': 'Director'})\n    query:\n        SELECT \n            employees.name,\n            positions.name,\n            departments.name \n        FROM \n            employees \n        JOIN positions ON \n            employees.position_id = positions.id \n        JOIN departments ON \n            positions.department_id = departments.id \n        WHERE \n            positions.name='Director'\n    result:\n        [\n            {'employees.name': 'Frank Franklin', 'positions.name': 'Director', 'departments.name': 'HR'}, \n            {'employees.name': 'Elly Doe', 'positions.name': 'Director', 'departments.name': 'Sales'}\n        ]\n\nSpecial Note: When performing multi-table joins, joining columns must be explicity provided. The key-value order is not explicity important, but will determine which column name is present in returned rows\n\n    join={'y_table': {'y_table.id': 'x_table.y_id'}}\n    result:\n        [\n            {'x_table.a': 'val1', 'y_table.id': 'val2'},\n            {'x_table.a': 'val1', 'y_table.id': 'val3'}\n        ]\nOR\n\n    join={'y_table': {'x_table.y_id': 'y_table.id'}}\n    result:\n        [\n            {'x_table.a': 'val1', 'x_table.y_id': 'val2'},\n            {'x_table.a': 'val1', 'x_table.y_id': 'val3'}\n        ]\n## Operator Syntax\nThe Following operators are supported within the list query syntax\n\n'=', '==', '\u003c\u003e', '!=', '\u003e', '\u003e=', '\u003c', '\u003c=', 'like', 'in', 'not in', 'not like'\n\nOperator Syntax Requires a list-of-lists and supports multiple combined conditions\n\n    #Syntax\n\n    db.tables['table'].select(\n        '*',\n        where=[[condition1], [condition2], [condition3]]\n    )\n\n\n    db.tables['table'].select(\n        '*',\n        where=[\n            ['col1', 'like', 'abc*'],\n            ['col2', '\u003c', 10],\n            ['col3', 'not in', ['a', 'b', 'c'] ]\n        ]\n    )\n\nExamples:\n\n    find_employee = db.tables['employees'].select(\n        'id', \n        'name',\n        where=[\n            ['name', 'like', '*ank*']\n        ]\n    )\n    query:\n        SELECT id,name FROM employees WHERE name like '%ank%'\n    result:\n        [{'id': 1016, 'name': 'Frank Franklin'}, {'id': 1018, 'name': 'Joe Franklin'}, {'id': 1020, 'name': 'Frank Franklin'}, {'id': 1034, 'name': 'Dana Franklin'}, {'id': 1036, 'name': 'Jane Franklin'}, {'id': 1042, 'name': 'Frank Franklin'}, {'id': 1043, 'name': 'Eli Franklin'}, {'id': 1052, 'name': 'Eli Franklin'}, {'id': 1057, 'name': 'Eli Franklin'}]\n\n\n\n    delete_department = db.tables['departments'].delete(\n        where=[\n            ['id', '\u003c', 2000]\n        ]\n    )\n    query:\n        DELETE \n            FROM \n                departments \n            WHERE \n                id \u003c 2000\n\n\n    join_sel = db.tables['employees'].select(\n        '*', \n        join={\n            'positions': {\n                'employees.position_id':'positions.id', \n                'positions.id': 'employees.position_id'\n            }\n        },\n        where=[\n            [\n                'positions.name', 'not in', ['Manager', 'Intern', 'Rep']\n            ],\n            [\n                'positions.department_id', '\u003c\u003e', 2001 # not equal\n            ]\n        ]\n    )\n    query:\n        SELECT \n            * \n        FROM \n            employees \n        JOIN \n            positions \n            ON \n                employees.position_id = positions.id  \n            AND  \n                positions.id = employees.position_id \n        WHERE \n            positions.name not in ('Manager', 'Intern', 'Rep') \n        AND \n            positions.department_id \u003c\u003e 2001\n\n\n\n\n#### Special Examples:\n\nBracket indexs can only be used for primary keys and return entire row, if existent\n\n    db.tables['employees'][1000]\n    query:\n        SELECT * FROM employees WHERE id=1000\n    result:\n        {'id': 1000, 'name': 'Frank Franklin', 'position_id': 100101}\n    \n\nIterate through table - grab all rows - allowing client side filtering \n\n    for row in db.tables['employees']:\n        print(row['id], row['name'])\n    query:\n        SELECT * FROM employees\n    result:\n        1000 Frank Franklin\n        1001 Eli Doe\n        1002 Chris Smith\n        1003 Clara Carson\n    \nUsing list comprehension\n\n    sel = [(row['id'], row['name']) for row in db.tables['employees']]\n    query:\n        SELECT * FROM employees\n    result:\n        [\n            (1000, 'Frank Franklin'), \n            (1001, 'Eli Doe'), \n            (1002, 'Chris Smith'), \n            (1003, 'Clara Carson'),\n            ...\n        ]\n\n\n### Update Data\n\nDefine update values in-line or un-pack\n\n    db.tables['stocks'].update(symbol='NTAP',trans='SELL', where={'order_num': 1})\n    query:\n        UPDATE stocks SET symbol = 'NTAP', trans = 'SELL' WHERE order_num=1\n\nUn-Pack\n\n    #JSON capable Data \n    tx_data = {'type': 'BUY', 'condition': {'limit': '36.00', 'time': 'end_of_trading_day'}}\n    to_update = {'symbol': 'NTAP', 'trans': tx_data}\n    where = {'order_num': 1}\n\n    db.tables['stocks'].update(**to_update, where=where)\n    query:\n        UPDATE \n            stocks \n        SET \n            symbol = 'NTAP', \n            trans = '{\"type\": \"BUY\", \"condition\": {\"limit\": \"36.00\", \"time\": \"end_of_trading_day\"}}' \n        WHERE \n            order_num=1\n\nBracket Assigment - Primary Key name assumed inside Brackets for value\n\n    #JSON capable Data \n\n    tx_data = {'type': 'BUY', 'condition': {'limit': '36.00', 'time': 'end_of_trading_day'}}\n    to_update = {'symbol': 'NTAP', 'trans': tx_data, 'qty': 500}\n\n    db.tables['stocks'][2] = to_update\n\n    query:\n        # check that primary_key value 2 exists\n        SELECT \n            * \n        FROM \n            stocks \n        WHERE \n            order_num=2\n\n        # update \n        UPDATE \n            stocks \n        SET \n            symbol = 'NTAP', \n            trans = '{\"type\": \"BUY\", \"condition\": {\"limit\": \"36.00\", \"time\": \"end_of_trading_day\"}}', \n            qty = 500 \n        WHERE \n            order_num=2\n\n    result:\n        db.tables['stocks'][2]\n        {\n            'order_num': 2, \n            'date': '2006-01-05', \n            'trans': {'type': 'BUY', 'condition': {'limit': '36.00', 'time': 'end_of_trading_day'}}, \n            'symbol': 'NTAP', \n            'qty': 500, \n            'price': 35.16, \n            'after_hours': True\n        }\n\n\n### Delete Data \n\n    db.tables['stocks'].delete(where={'order_num': 1})\n\n### Other\nTable Exists\n\n    'employees' in db\n    query:\n        show tables\n    result:\n        True\n\nPrimary Key Exists:\n\n    1000 in db.tables['employees']\n    query:\n        SELECT * FROM employees WHERE id=1000\n    result:\n        True","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemation%2Fpyql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodemation%2Fpyql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodemation%2Fpyql/lists"}