Metadata-Version: 2.4
Name: pg-query-python
Version: 0.1.3
Summary: Python bindings for libpg_query — parse, deparse, and walk PostgreSQL SQL statements
Author-email: Trail <joanna@trail-ml.com>
License: BSD-3-Clause
Project-URL: Homepage, https://github.com/trail-ml/pg-query-python
Project-URL: Repository, https://github.com/trail-ml/pg-query-python
Keywords: postgresql,sql,parser,ast,libpg_query
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: protobuf>=4.0
Provides-Extra: dev
Requires-Dist: grpcio-tools>=1.60; extra == "dev"
Dynamic: license-file

# pg-query-python

Python bindings for [libpg_query](https://github.com/pganalyze/libpg_query) — parse, deparse, and walk PostgreSQL SQL statements.

Ships pre-built wheels with the `libpg_query` shared library for Linux (x86_64, aarch64) and macOS (x86_64, arm64). No compiler required at install time.

## Install

```bash
pip install pg-query-python
```

## Usage

### Parse SQL to a protobuf AST

```python
from pg_query import parse

tree = parse("SELECT id, name FROM users WHERE active = true")
print(tree)
```

### Deparse an AST back to SQL

```python
from pg_query import parse, deparse

tree = parse("SELECT 1")
sql = deparse(tree)
assert sql == "SELECT 1"
```

### Walk the AST

```python
from pg_query import parse, walk

tree = parse("SELECT id FROM users JOIN orders ON users.id = orders.user_id")
for field_name, node in walk(tree):
    if type(node).DESCRIPTOR.name == "RangeVar":
        print(f"Table: {node.relname}")
```

### Visitor pattern

```python
from pg_query import parse, Visitor

class TableFinder(Visitor):
    def __init__(self):
        self.tables = []

    def visit_RangeVar(self, node):
        self.tables.append(node.relname)

tree = parse("SELECT * FROM users, orders")
finder = TableFinder()
finder.visit(tree)
print(finder.tables)  # ['users', 'orders']
```

## Building from source

If no pre-built wheel is available for your platform, pip will build from source. You'll need `git`, `make`, and a C compiler:

```bash
pip install pg-query-python --no-binary pg-query-python
```

To target a specific libpg_query version:

```bash
LIBPG_QUERY_TAG=16-latest pip install pg-query-python --no-binary pg-query-python
```

## License

BSD-3-Clause (this package) and BSD-3-Clause + PostgreSQL License (libpg_query).
