gqlbridge


Namegqlbridge JSON
Version 1.0.3 PyPI version JSON
download
home_pageNone
SummaryExecute GraphQL-style queries on PostgreSQL and return nested JSON results.
upload_time2025-09-06 12:20:36
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords graphql sql postgresql json etl data engineering
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # GQLBridge

This package allows you to write GraphQL-style queries against a PostgreSQL database and automatically converts them into SQL queries that return nested JSON results.

### It is especially useful for:

* **Organizations** that want to query relational data sources (PostgreSQL) using GraphQL-like queries, without needing to set up a full GraphQL server.
* **Developers & data engineers** who work with analytics pipelines, ETL processes, or APIs and want an easy way to express complex relational queries in a GraphQL-like syntax.
* **Teams** that want **GraphQL as a query interface** for their data warehouse but keep execution in **SQL (PostgreSQL)** for performance and compatibility.


### Key Features

* **GraphQL-style input**: Accepts GraphQL query strings directly as input.
* **Automatic SQL generation**: Converts nested selections, filters, joins, and lists into PostgreSQL SQL queries.
* **JSON output**: Returns query results as nested JSON objects for direct consumption in APIs or applications.
* **Join handling**: Supports `LEFT`, `RIGHT`, `INNER`, `FULL`, and `CROSS` joins defined via GraphQL arguments.
* **Filter support**: Handles comparison operators (`eq`, `ne`, `lt`, `gt`, `le`, `ge`) and list-based filters.
* **Pagination**: Supports **pagination** with `first`, `after`, and `orderBy`.
* **Date handling**: Automatically parses and casts date strings into `TIMESTAMP`.
* **Integration ready**: Returns results as Python dictionaries (via Pandas + JSON), suitable for APIs, ETL, or downstream analytics.

### Installation

```
pip install gqlbridge
```

### Environment Variables

Before running queries, configure your PostgreSQL connection using environment variables:

```
export DB_HOST=your-db-host
export DB_PORT=your-db-port
export DB_NAME=your-database
export DB_USER=your-username
export DB_PASSWORD=your-password
```

### How Queries Work

Queries are written in GraphQL style, but instead of hitting a GraphQL API, this package translates them into PostgreSQL and executes them against PostgreSQL.

General Structure query

``` graphql
query {
  project(path: {eq:"demo_project"}) {
    id
    name
    description
  }
}
```

* `project` → **Outer table** (the main table you are selecting from).
* `path: {eq:"demo_project"}` → **Filter condition** (`WHERE path = 'demo_project'`).
* `id, name, description` → **Columns** to select.

#### Joins

This package supports joins between tables using GraphQL arguments.

#### Example with Joins

``` graphql
query {
  project(path: {eq:"demo_project"}) {
    id
    name
    description

    join_table1(left: {id: "eq-project_id"}, title: {eq:"Bug Fix"}) {
      id
      title
    }

    join_table2(left: {id: "eq-project_id"}) {
      id
      project_id
    }
  }
}
```

#### Explanation:

1. **Outer Table**
   * `project` is the **main table**.
   * The filter `path: {eq:"demo_project"}"` applies as a SQL `WHERE` clause.
2. **Join Tables**
   * `join_table1` and `join_table2` represent tables joined with `project`.
   * `left` specifies the **join type** (`LEFT JOIN`).
   * Supported join types: `left`, `right`, `inner`, `full`, `cross`.
3. **Join Condition (`id: "eq-project_id"`)**
   * This means:
     * `id` belongs to the **main table** (`project`).
     * `project_id` belongs to the **join table** (`join_table1` or `join_table2`).
   * Interpreted as:

     `project.id = join_table1.project_id
     `
4. **Filters on Join Table**
   * `title: {eq:"Bug Fix"}` applies as a `WHERE` filter inside the join.

---

#### JSON Fields

If a column in the database stores **JSON data**, you can request nested fields using GraphQL notation.

#### Example: Extracting JSON

``` graphql
query {
  project(path: {eq:"demo_project"}) {
    id
    metadata {
      name
      version
    }
  }
}
```

This extracts `metadata.name` and `metadata.version` from the `metadata` JSON column.

---

#### JSON Lists (`list_items`)

When a JSON field contains a **list (array)**, you must use `list_items` to expand it.

#### Example: JSON Array

``` graphql
query {
  project(path: {eq:"demo_project"}) {
    id
    metadata {
      name
      tags {
        list_items {
          key
          value
        }
      }
    }
  }
}
```

* `metadata.tags` is a **list field**.
* `list_items` tells the query engine to expand the array elements.
* Equivalent SQL logic uses `jsonb_array_elements`.

---

#### Pagination

With pagination, you can easily control how many rows to fetch, where to start, and the order of results — all directly in your GraphQL-style query.

#### Example: Pagination
``` graphql
query {
  project(first: 3, after: 2, orderBy: "id") {
    id
    name
    fullPath
    description
  }
}
```

* first: 3 → limit results to 3 rows
* after: 2 → offset (skip) the first page - first 3 rows
* orderBy: "id" → order results by column id

---

### End-to-End Example

#### Input Query

``` graphql
query {
  project(path: {eq:"demo_project"}) {
    id
    name
    description

    join_table1(left: {id: "eq-project_id"}, title: {eq:"Bug Fix"}) {
      id
      title
    }

    join_table2(left: {id: "eq-project_id"}) {
      id
      project_id
    }

    metadata {
      name
      tags {
        list_items {
          key
          value
        }
      }
    }
  }
}
```

#### Output JSON

``` json
{
  "Query1": [
    {
      "id": 1,
      "name": "Demo Project",
      "description": "A test project",
      "join_table1": [
        { "id": 101, "title": "Bug Fix" }
      ],
      "join_table2": [
        { "id": 201, "project_id": 1 }
      ],
      "metadata": {
        "name": "Project Metadata",
        "tags": [
          { "key": "priority", "value": "high" },
          { "key": "status", "value": "active" }
        ]
      }
    }
  ]
}
```

### Supported Features

* ✅ GraphQL-style query input (string-based).
* ✅ Automatic translation to PostgreSQL SQL.
* ✅ Supports **joins** (`LEFT`, `RIGHT`, `INNER`, `FULL`, `CROSS`).
* ✅ Supports **comparison operators** (`eq`, `ne`, `lt`, `le`, `gt`, `ge`).
* ✅ Handles **string, numeric, and timestamp filters**.
* ✅ Extracts and structures **JSON and JSON arrays** with `list_items`.
* ✅ Returns results as **nested JSON** matching the GraphQL query shape.

### Audience

* **Data engineers**: Simplify ETL pipelines with GraphQL queries on SQL data.
* **Backend developers**: Expose data without writing raw SQL.
* **Organizations**: Provide a query interface for PostgreSQL that feels like GraphQL.
* **Analysts**: Explore relational data using GraphQL syntax.

### License

MIT License.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "gqlbridge",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "GraphQL, SQL, PostgreSQL, JSON, ETL, Data Engineering",
    "author": null,
    "author_email": "Harshavardhan Chitakana <chharshavardhan2001@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/c1/f1/24afe2c2f5ca2c2996e963c9326e4a1150af00691d6b730b200478238f26/gqlbridge-1.0.3.tar.gz",
    "platform": null,
    "description": "# GQLBridge\n\nThis package allows you to write GraphQL-style queries against a PostgreSQL database and automatically converts them into SQL queries that return nested JSON results.\n\n### It is especially useful for:\n\n* **Organizations** that want to query relational data sources (PostgreSQL) using GraphQL-like queries, without needing to set up a full GraphQL server.\n* **Developers & data engineers** who work with analytics pipelines, ETL processes, or APIs and want an easy way to express complex relational queries in a GraphQL-like syntax.\n* **Teams** that want **GraphQL as a query interface** for their data warehouse but keep execution in **SQL (PostgreSQL)** for performance and compatibility.\n\n\n### Key Features\n\n* **GraphQL-style input**: Accepts GraphQL query strings directly as input.\n* **Automatic SQL generation**: Converts nested selections, filters, joins, and lists into PostgreSQL SQL queries.\n* **JSON output**: Returns query results as nested JSON objects for direct consumption in APIs or applications.\n* **Join handling**: Supports `LEFT`, `RIGHT`, `INNER`, `FULL`, and `CROSS` joins defined via GraphQL arguments.\n* **Filter support**: Handles comparison operators (`eq`, `ne`, `lt`, `gt`, `le`, `ge`) and list-based filters.\n* **Pagination**: Supports **pagination** with `first`, `after`, and `orderBy`.\n* **Date handling**: Automatically parses and casts date strings into `TIMESTAMP`.\n* **Integration ready**: Returns results as Python dictionaries (via Pandas + JSON), suitable for APIs, ETL, or downstream analytics.\n\n### Installation\n\n```\npip install gqlbridge\n```\n\n### Environment Variables\n\nBefore running queries, configure your PostgreSQL connection using environment variables:\n\n```\nexport DB_HOST=your-db-host\nexport DB_PORT=your-db-port\nexport DB_NAME=your-database\nexport DB_USER=your-username\nexport DB_PASSWORD=your-password\n```\n\n### How Queries Work\n\nQueries are written in GraphQL style, but instead of hitting a GraphQL API, this package translates them into PostgreSQL and executes them against PostgreSQL.\n\nGeneral Structure query\n\n``` graphql\nquery {\n  project(path: {eq:\"demo_project\"}) {\n    id\n    name\n    description\n  }\n}\n```\n\n* `project` \u2192 **Outer table** (the main table you are selecting from).\n* `path: {eq:\"demo_project\"}` \u2192 **Filter condition** (`WHERE path = 'demo_project'`).\n* `id, name, description` \u2192 **Columns** to select.\n\n#### Joins\n\nThis package supports joins between tables using GraphQL arguments.\n\n#### Example with Joins\n\n``` graphql\nquery {\n  project(path: {eq:\"demo_project\"}) {\n    id\n    name\n    description\n\n    join_table1(left: {id: \"eq-project_id\"}, title: {eq:\"Bug Fix\"}) {\n      id\n      title\n    }\n\n    join_table2(left: {id: \"eq-project_id\"}) {\n      id\n      project_id\n    }\n  }\n}\n```\n\n#### Explanation:\n\n1. **Outer Table**\n   * `project` is the **main table**.\n   * The filter `path: {eq:\"demo_project\"}\"` applies as a SQL `WHERE` clause.\n2. **Join Tables**\n   * `join_table1` and `join_table2` represent tables joined with `project`.\n   * `left` specifies the **join type** (`LEFT JOIN`).\n   * Supported join types: `left`, `right`, `inner`, `full`, `cross`.\n3. **Join Condition (`id: \"eq-project_id\"`)**\n   * This means:\n     * `id` belongs to the **main table** (`project`).\n     * `project_id` belongs to the **join table** (`join_table1` or `join_table2`).\n   * Interpreted as:\n\n     `project.id = join_table1.project_id\n     `\n4. **Filters on Join Table**\n   * `title: {eq:\"Bug Fix\"}` applies as a `WHERE` filter inside the join.\n\n---\n\n#### JSON Fields\n\nIf a column in the database stores **JSON data**, you can request nested fields using GraphQL notation.\n\n#### Example: Extracting JSON\n\n``` graphql\nquery {\n  project(path: {eq:\"demo_project\"}) {\n    id\n    metadata {\n      name\n      version\n    }\n  }\n}\n```\n\nThis extracts `metadata.name` and `metadata.version` from the `metadata` JSON column.\n\n---\n\n#### JSON Lists (`list_items`)\n\nWhen a JSON field contains a **list (array)**, you must use `list_items` to expand it.\n\n#### Example: JSON Array\n\n``` graphql\nquery {\n  project(path: {eq:\"demo_project\"}) {\n    id\n    metadata {\n      name\n      tags {\n        list_items {\n          key\n          value\n        }\n      }\n    }\n  }\n}\n```\n\n* `metadata.tags` is a **list field**.\n* `list_items` tells the query engine to expand the array elements.\n* Equivalent SQL logic uses `jsonb_array_elements`.\n\n---\n\n#### Pagination\n\nWith pagination, you can easily control how many rows to fetch, where to start, and the order of results \u2014 all directly in your GraphQL-style query.\n\n#### Example: Pagination\n``` graphql\nquery {\n  project(first: 3, after: 2, orderBy: \"id\") {\n    id\n    name\n    fullPath\n    description\n  }\n}\n```\n\n* first: 3 \u2192 limit results to 3 rows\n* after: 2 \u2192 offset (skip) the first page - first 3 rows\n* orderBy: \"id\" \u2192 order results by column id\n\n---\n\n### End-to-End Example\n\n#### Input Query\n\n``` graphql\nquery {\n  project(path: {eq:\"demo_project\"}) {\n    id\n    name\n    description\n\n    join_table1(left: {id: \"eq-project_id\"}, title: {eq:\"Bug Fix\"}) {\n      id\n      title\n    }\n\n    join_table2(left: {id: \"eq-project_id\"}) {\n      id\n      project_id\n    }\n\n    metadata {\n      name\n      tags {\n        list_items {\n          key\n          value\n        }\n      }\n    }\n  }\n}\n```\n\n#### Output JSON\n\n``` json\n{\n  \"Query1\": [\n    {\n      \"id\": 1,\n      \"name\": \"Demo Project\",\n      \"description\": \"A test project\",\n      \"join_table1\": [\n        { \"id\": 101, \"title\": \"Bug Fix\" }\n      ],\n      \"join_table2\": [\n        { \"id\": 201, \"project_id\": 1 }\n      ],\n      \"metadata\": {\n        \"name\": \"Project Metadata\",\n        \"tags\": [\n          { \"key\": \"priority\", \"value\": \"high\" },\n          { \"key\": \"status\", \"value\": \"active\" }\n        ]\n      }\n    }\n  ]\n}\n```\n\n### Supported Features\n\n* \u2705 GraphQL-style query input (string-based).\n* \u2705 Automatic translation to PostgreSQL SQL.\n* \u2705 Supports **joins** (`LEFT`, `RIGHT`, `INNER`, `FULL`, `CROSS`).\n* \u2705 Supports **comparison operators** (`eq`, `ne`, `lt`, `le`, `gt`, `ge`).\n* \u2705 Handles **string, numeric, and timestamp filters**.\n* \u2705 Extracts and structures **JSON and JSON arrays** with `list_items`.\n* \u2705 Returns results as **nested JSON** matching the GraphQL query shape.\n\n### Audience\n\n* **Data engineers**: Simplify ETL pipelines with GraphQL queries on SQL data.\n* **Backend developers**: Expose data without writing raw SQL.\n* **Organizations**: Provide a query interface for PostgreSQL that feels like GraphQL.\n* **Analysts**: Explore relational data using GraphQL syntax.\n\n### License\n\nMIT License.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Execute GraphQL-style queries on PostgreSQL and return nested JSON results.",
    "version": "1.0.3",
    "project_urls": {
        "Documentation": "https://github.com/HarshaChitakana/GQLBridge#readme",
        "Homepage": "https://github.com/HarshaChitakana/GQLBridge",
        "Repository": "https://github.com/HarshaChitakana/GQLBridge"
    },
    "split_keywords": [
        "graphql",
        " sql",
        " postgresql",
        " json",
        " etl",
        " data engineering"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5657a10810bf79292fd7248cf96adc4045b8b0a53da3a0daa42d7b36070cff1f",
                "md5": "934a15ae59ba9238b77b90a122bcff3c",
                "sha256": "2ba7ee6925fb1ad99547b5db8c0379ee5d24350ef7b344caa0cc8b52cfe70285"
            },
            "downloads": -1,
            "filename": "gqlbridge-1.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "934a15ae59ba9238b77b90a122bcff3c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 8722,
            "upload_time": "2025-09-06T12:20:35",
            "upload_time_iso_8601": "2025-09-06T12:20:35.061644Z",
            "url": "https://files.pythonhosted.org/packages/56/57/a10810bf79292fd7248cf96adc4045b8b0a53da3a0daa42d7b36070cff1f/gqlbridge-1.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c1f124afe2c2f5ca2c2996e963c9326e4a1150af00691d6b730b200478238f26",
                "md5": "8dd26d1e65f1d6889fbffca7eb576c17",
                "sha256": "fc75f69f7cd0f82fcb8928a7c4e46274a1f1b52842f60224f1e8bbb8023e98a4"
            },
            "downloads": -1,
            "filename": "gqlbridge-1.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "8dd26d1e65f1d6889fbffca7eb576c17",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 10846,
            "upload_time": "2025-09-06T12:20:36",
            "upload_time_iso_8601": "2025-09-06T12:20:36.476994Z",
            "url": "https://files.pythonhosted.org/packages/c1/f1/24afe2c2f5ca2c2996e963c9326e4a1150af00691d6b730b200478238f26/gqlbridge-1.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-06 12:20:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "HarshaChitakana",
    "github_project": "GQLBridge#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "gqlbridge"
}
        
Elapsed time: 1.37743s