{"id":37065048,"url":"https://github.com/lokhman/pydbal","last_synced_at":"2026-01-14T07:36:36.120Z","repository":{"id":62579793,"uuid":"54664147","full_name":"lokhman/pydbal","owner":"lokhman","description":"Optimised Database Abstraction Layer (DBAL) for Python 2.6+","archived":false,"fork":false,"pushed_at":"2017-02-06T15:06:34.000Z","size":78,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-27T12:25:45.341Z","etag":null,"topics":["abstraction","database","library","python"],"latest_commit_sha":null,"homepage":"https://lokhman.github.io/pydbal/","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/lokhman.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":"2016-03-24T18:17:10.000Z","updated_at":"2021-12-03T18:24:26.000Z","dependencies_parsed_at":"2022-11-03T21:01:03.515Z","dependency_job_id":null,"html_url":"https://github.com/lokhman/pydbal","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/lokhman/pydbal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lokhman%2Fpydbal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lokhman%2Fpydbal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lokhman%2Fpydbal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lokhman%2Fpydbal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lokhman","download_url":"https://codeload.github.com/lokhman/pydbal/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lokhman%2Fpydbal/sbom","scorecard":{"id":597686,"data":{"date":"2025-08-11","repo":{"name":"github.com/lokhman/pydbal","commit":"53f396a2a18826e9fff178cd2c0636c1656cbaea"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}}]},"last_synced_at":"2025-08-20T23:33:57.934Z","repository_id":62579793,"created_at":"2025-08-20T23:33:57.934Z","updated_at":"2025-08-20T23:33:57.934Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["abstraction","database","library","python"],"created_at":"2026-01-14T07:36:35.505Z","updated_at":"2026-01-14T07:36:36.111Z","avatar_url":"https://github.com/lokhman.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"pyDBAL\n======\n\nDatabase Abstraction Layer (**DBAL**) for Python 2.6+.\n\npyDBAL library is the improved and optimised port of [Doctrine\nDBAL](http://www.doctrine-project.org/projects/dbal.html) project.\n\nInstallation\n------------\n\n    $ pip install pydbal\n\nRequirements\n------------\n\nFor using `mysql` driver `MySQLdb` library is required. Optionally\n`lrucache` is required to maintain memory safe cache operations.\n\nBasic Usage\n-----------\n\nTo open new connection import `Connection` from `pydbal.connection`\npackage and initialise `Connection` class for a required driver with\ndesired parameters.\n\n    from pydbal.connection import Connection\n\n    conn = Connection('mysql', host='localhost', user='root', database='mydb')\n\npyDBAL currently supports the following drivers: `mysql` and `sqlite`.\nYou can create a custom driver by inheriting `pydbal.drivers.BaseDriver`\nand passing to `Connection` constructor.\n\n### Query Statements\n\nTo **SELECT** data from the database you may use `query` method. This\nmethod will return the instance of `pydbal.statement.Statement`.\n\n    # simple fetch generator\n    for row in conn.query('SELECT * FROM table'):\n        print(row)\n\n    # same as the above but fetch mode can be applied (Connection.FETCH_*)\n    for row in conn.query('SELECT * FROM table').iterate(fetch_mode=Connection.FETCH_OBJECT):\n        print(row)\n\n    # fetch row by row\n    result = conn.query('SELECT * FROM table')\n    row1 = result.fetch()\n    row2 = result.fetch()\n\n    # fetch all rows\n    rows = conn.query('SELECT * FROM table').fetch_all()\n\n    # fetch single value from column\n    count = conn.query('SELECT COUNT(*) FROM table').fetch_column()\n\n    # fetch all values from column by index\n    ids = conn.query('SELECT id FROM table').fetch_all(fetch_mode=Connection.FETCH_COLUMN, column_index=0)\n\n### Execute Statements\n\nTo execute **INSERT**, **UPDATE** or **DELETE** statements you may use\n`execute` method. This method will return number of affected rows.\n\n    # INSERT\n    conn.execute('INSERT INTO table VALUES (?)', [val1, val2, val3])\n    last_insert_id = conn.last_insert_id()\n\n    # UPDATE\n    affected_rows = conn.execute('UPDATE table SET column = ? WHERE id = ?', val1, id_)\n\n    # DELETE\n    affected_rows = conn.execute('DELETE FROM table WHERE id = ?', id_)\n\n### Statement Parameters\n\nBoth `query` and `execute` methods support safe parameter binding by\npassing arguments after the first `sql` argument.\n\n    # single positional parameter\n    row = conn.query('SELECT * FROM table WHERE id = ?', id_).fetch()\n\n    # multiple positional parameters\n    row = conn.query('SELECT * FROM table WHERE id = ? OR id = ?', id1, id2).fetch()\n\n    # named parameters\n    row = conn.query('SELECT * FROM table WHERE id = :id1 OR id = :id2', id1=id1, id2=id2).fetch()\n\n    # iterable parameters\n    row = conn.query('SELECT * FROM table WHERE id IN (?)', [id1, id2]).fetch()\n\n### Transactions\n\npyDBAL supports transactional operations.\n\n    conn.begin_transaction()\n    try:\n        # ... execute statements ...\n        conn.commit()\n        return smth\n    except:\n        conn.rollback()\n        raise\n\n    # same as the above\n    def trans(conn):\n        # ... execute statements ...\n        return smth\n    smth = conn.transaction(trans)\n\nIf database platform supports *savepoints* you may enable and use nested\ntransactions.\n\n    conn.set_nest_transactions_with_savepoints(True)\n    conn.begin_transaction()\n    # ... execute statements 1 ...\n    conn.begin_transaction()\n    # ... execute statements 2 ...\n    conn.commit()  # commit 1\n    conn.rollback()  # rollback 2\n\n    # to control savepoints manually\n    conn.create_savepoint('MYSAVEPOINT')\n    conn.release_savepoint('MYSAVEPOINT')\n    conn.rollback_savepoint('MYSAVEPOINT')\n\n### SQL Builder\n\nTo make writing SQL statements more simple and flexible it's suggested\nto use `pydbal.builder.SQLBuilder`.\n\n    # SELECT\n    sqb = (\n        conn.sql_builder()\n            .select('t1.id', 't2.id', 'SUM(t1.col) AS special')\n            .from_('table1', 't1')\n            .join('t1', 'table2', 't2', 't2.id = t1.id')\n            .where('t1.col = :val')\n            .set_parameter('val', val)\n            .group_by('t1.col')\n            .having('special IS NOT NULL')\n            .order_by('t2.id')\n    )\n    for row in sqb.execute():\n        print(row)\n\n    # INSERT\n    last_insert_id = (\n        conn.sql_builder()\n            .insert('table')\n            .values({'col1': val1, 'col2': val2})\n    ).execute()\n\n    # UPDATE\n    affected_rows = (\n        conn.sql_builder()\n            .update('table')\n            .set('col1', val1)\n            .set('col2', val2)\n            .where('id = :id')\n            .set_parameter('id', id_)\n    ).execute()\n\n    # DELETE\n    affected_rows = (\n        conn.sql_builder()\n            .delete('table')\n            .where('id = ?')\n            .set_parameter(0, id_)\n    ).execute()\n\n### Expression Builder\n\n`WHERE`, `HAVING` and `JOIN ... ON` expressions can be created using\n`pydbal.builder.ExpressionBuilder`.\n\n    expr = conn.get_expression_builder()\n    # or via SQL Builder instance\n    # expr = sqb.expr()\n\n    sqb.where(\n        expr.and_x(expr.eq('a', 'b'), expr.is_null('c'))\n            .or_x(\n                expr.and_x('d IS NULL', expr.in_('e', ['1', '2', '3'])),\n                expr.neq('f', expr.literal('abc'))\n            )\n    )\n\n### Schema Manager\n\npyDBAL comes with simple read only SQL schema manager. It supports\nlisting of databases, tables, views, columns, indexes and foreign keys.\nInternal database queries are cached with `pydbal.cache` mechanisms.\n\n    sm = conn.get_schema_manager()\n\n    # database names\n    db_names = sm.get_database_names()\n\n    # views\n    views = sm.get_views()\n    view_names = sm.get_view_names()\n\n    # tables\n    tables = sm.get_tables()\n    table_names = sm.get_table_names()\n\n    # columns\n    table_columns = sm.get_table_columns('table')\n    table_column_names = sm.get_table_column_names('table')\n\n    # indexes\n    table_indexes = sm.get_table_indexes('table')\n    table_index_names = sm.get_table_index_names('table')\n\n    # foreign keys\n    table_foreign_keys = sm.get_table_foreign_keys('table')\n    table_foreign_key_names = sm.get_table_foreign_key_names('table')\n\n### Thread-safe Connection\n\npyDBAL v0.10+ supports thread-safe connection functionality implemented\nin `pydbal.threading` module.\n\n    from pydbal.threading import SafeConnection\n\n    conn = SafeConnection('mysql', host='localhost', user='root', database='mydb')\n\n`SafeConnection` wrapper class maintains active connections in locked\npool and provides helper methods for manipulating your data. Class\nimplements method `locked()` which should be passed to `with` statement.\nIt generates isolated connection context, that can be used for sending\nnon-trivial commands to the original `pydbal.connection.Connection`\nobject.\n\n    # simple fetch generator\n    for row in conn.query('SELECT * FROM table'):\n        print(row)\n\n    # fetch one row\n    row = conn.fetch('SELECT * FROM table WHERE id = ?', id_)\n\n    # fetch all rows\n    rows = conn.fetch_all('SELECT * FROM table')\n\n    # fetch single value from column\n    count = conn.fetch_column('SELECT COUNT(*) FROM table')\n\n    # UPDATE or DELETE queries\n    affected_rows = conn.execute('UPDATE table SET column = ? WHERE id = ?', val1, id_)\n\n    # INSERT query with last inserted ID\n    with conn.locked() as _conn:\n        _conn.execute('INSERT INTO table VALUES (?)', [val1, val2, val3])\n        last_insert_id = _conn.last_insert_id()\n\n    # transaction callback\n    def trans(_conn):\n        # ... execute statements ...\n        return smth\n    smth = conn.transaction(trans)\n\nLicense\n-------\n\nLibrary is available under the MIT license. The included LICENSE file\ndescribes this in detail.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flokhman%2Fpydbal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flokhman%2Fpydbal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flokhman%2Fpydbal/lists"}