buildaquery 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {buildaquery-0.2.0 → buildaquery-0.3.0}/PKG-INFO +57 -7
- {buildaquery-0.2.0 → buildaquery-0.3.0}/README.md +68 -19
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/abstract_syntax_tree/README.md +1 -1
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/compiler/README.md +16 -1
- buildaquery-0.3.0/buildaquery/compiler/__init__.py +5 -0
- buildaquery-0.3.0/buildaquery/compiler/mysql/README.md +25 -0
- buildaquery-0.3.0/buildaquery/compiler/mysql/__init__.py +1 -0
- buildaquery-0.3.0/buildaquery/compiler/mysql/mysql_compiler.py +342 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/compiler/postgres/README.md +1 -1
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/compiler/sqlite/README.md +2 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/execution/README.md +5 -1
- buildaquery-0.3.0/buildaquery/execution/__init__.py +5 -0
- buildaquery-0.3.0/buildaquery/execution/mysql.py +185 -0
- buildaquery-0.3.0/buildaquery/tests/test_compiler_mysql.py +341 -0
- buildaquery-0.3.0/buildaquery/tests/test_execution_mysql.py +51 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/traversal/README.md +1 -1
- {buildaquery-0.2.0 → buildaquery-0.3.0}/pyproject.toml +10 -9
- buildaquery-0.2.0/buildaquery/compiler/__init__.py +0 -0
- buildaquery-0.2.0/buildaquery/execution/__init__.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/LICENSE.txt +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/__init__.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/abstract_syntax_tree/__init__.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/abstract_syntax_tree/models.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/compiler/compiled_query.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/compiler/postgres/postgres_compiler.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/compiler/sqlite/__init__.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/compiler/sqlite/sqlite_compiler.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/execution/base.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/execution/postgres.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/execution/sqlite.py +0 -0
- /buildaquery-0.2.0/buildaquery/tests/test_ast.py → /buildaquery-0.3.0/buildaquery/tests/test_ast_postgres.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/tests/test_compiler_postgres.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/tests/test_compiler_sqlite.py +0 -0
- /buildaquery-0.2.0/buildaquery/tests/test_execution.py → /buildaquery-0.3.0/buildaquery/tests/test_execution_postgres.py +0 -0
- /buildaquery-0.2.0/buildaquery/tests/test_traversal.py → /buildaquery-0.3.0/buildaquery/tests/test_traversal_postgres.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/traversal/__init__.py +0 -0
- {buildaquery-0.2.0 → buildaquery-0.3.0}/buildaquery/traversal/visitor_pattern.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: buildaquery
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A Python-based query builder for PostgreSQL.
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A Python-based query builder for PostgreSQL, SQLite, and MySQL.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE.txt
|
|
7
7
|
Author: Anirudh Bhattacharya
|
|
@@ -21,6 +21,7 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
22
|
Requires-Dist: Pygments (==2.19.2)
|
|
23
23
|
Requires-Dist: colorama (==0.4.6)
|
|
24
|
+
Requires-Dist: mysql-connector-python (==9.4.0)
|
|
24
25
|
Requires-Dist: packaging (==26.0)
|
|
25
26
|
Requires-Dist: pluggy (==1.6.0)
|
|
26
27
|
Requires-Dist: psycopg (==3.3.3)
|
|
@@ -33,7 +34,7 @@ Description-Content-Type: text/markdown
|
|
|
33
34
|
|
|
34
35
|
# Build-a-Query
|
|
35
36
|
|
|
36
|
-
A Python-based query builder designed to represent, compile, and execute SQL queries using a dialect-agnostic Abstract Syntax Tree (AST). Supports PostgreSQL and
|
|
37
|
+
A Python-based query builder designed to represent, compile, and execute SQL queries using a dialect-agnostic Abstract Syntax Tree (AST). Supports PostgreSQL, SQLite, and MySQL.
|
|
37
38
|
|
|
38
39
|
## Features
|
|
39
40
|
|
|
@@ -44,7 +45,11 @@ A Python-based query builder designed to represent, compile, and execute SQL que
|
|
|
44
45
|
- **DDL Support**: Basic schema management with `CREATE TABLE` and `DROP TABLE`.
|
|
45
46
|
- **Visitor Pattern Traversal**: Extensible architecture for analysis and compilation.
|
|
46
47
|
- **Secure Compilation**: Automatic parameterization to prevent SQL injection.
|
|
47
|
-
- **Execution Layer**: Built-in support for executing compiled queries via `psycopg` (PostgreSQL) and the standard library `sqlite3` (SQLite).
|
|
48
|
+
- **Execution Layer**: Built-in support for executing compiled queries via `psycopg` (PostgreSQL), `mysql-connector-python` (MySQL), and the standard library `sqlite3` (SQLite).
|
|
49
|
+
|
|
50
|
+
## Dialect Notes
|
|
51
|
+
- MySQL does not support `INTERSECT` / `EXCEPT` or `DROP TABLE ... CASCADE` in this implementation (the compiler raises `ValueError`).
|
|
52
|
+
- SQLite does not support `DROP TABLE ... CASCADE` (the compiler raises `ValueError`).
|
|
48
53
|
|
|
49
54
|
## Installation
|
|
50
55
|
|
|
@@ -61,6 +66,9 @@ pip install buildaquery
|
|
|
61
66
|
- **PostgreSQL database**: A running PostgreSQL instance (version 12+ recommended). You can set this up locally, via Docker, or use a cloud service.
|
|
62
67
|
- Example with Docker: `docker run --name postgres -e POSTGRES_PASSWORD=yourpassword -d -p 5432:5432 postgres:15`
|
|
63
68
|
- `psycopg` (automatically installed as a dependency) - the PostgreSQL adapter for Python.
|
|
69
|
+
- **MySQL database**: A running MySQL instance (version 8.0+ recommended).
|
|
70
|
+
- Example with Docker: `docker run --name mysql -e MYSQL_ROOT_PASSWORD=yourpassword -e MYSQL_DATABASE=buildaquery -d -p 3306:3306 mysql:8.0`
|
|
71
|
+
- `mysql-connector-python` (automatically installed as a dependency) - the MySQL adapter for Python.
|
|
64
72
|
- `python-dotenv` (automatically installed as a dependency) - for loading environment variables from a `.env` file.
|
|
65
73
|
- **SQLite**: Uses Python's standard library `sqlite3` module.
|
|
66
74
|
- **SQLite Version**: SQLite 3.x via Python's `sqlite3` module (the exact SQLite version depends on your Python build; check `sqlite3.sqlite_version` at runtime).
|
|
@@ -84,6 +92,8 @@ DB_USER=postgres
|
|
|
84
92
|
DB_PASSWORD=yourpassword
|
|
85
93
|
```
|
|
86
94
|
|
|
95
|
+
For MySQL, you can use a connection URL directly in code (e.g., `mysql://user:password@host:3306/dbname`) or set your own environment variables and construct the URL similarly.
|
|
96
|
+
|
|
87
97
|
### For Developers
|
|
88
98
|
|
|
89
99
|
Clone the repository and set up the development environment:
|
|
@@ -209,7 +219,47 @@ drop_stmt = DropStatementNode(table=users_table, if_exists=True)
|
|
|
209
219
|
executor.execute(drop_stmt)
|
|
210
220
|
```
|
|
211
221
|
|
|
212
|
-
|
|
222
|
+
### MySQL Quick Start
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
from buildaquery.execution.mysql import MySqlExecutor
|
|
226
|
+
from buildaquery.abstract_syntax_tree.models import (
|
|
227
|
+
CreateStatementNode, TableNode, ColumnDefinitionNode,
|
|
228
|
+
InsertStatementNode, ColumnNode, LiteralNode,
|
|
229
|
+
SelectStatementNode, StarNode, DropStatementNode
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
executor = MySqlExecutor(connection_info="mysql://root:password@127.0.0.1:3306/buildaquery")
|
|
233
|
+
|
|
234
|
+
users_table = TableNode(name="users")
|
|
235
|
+
create_stmt = CreateStatementNode(
|
|
236
|
+
table=users_table,
|
|
237
|
+
columns=[
|
|
238
|
+
ColumnDefinitionNode(name="id", data_type="INT AUTO_INCREMENT", primary_key=True),
|
|
239
|
+
ColumnDefinitionNode(name="name", data_type="VARCHAR(255)", not_null=True),
|
|
240
|
+
ColumnDefinitionNode(name="age", data_type="INT")
|
|
241
|
+
]
|
|
242
|
+
)
|
|
243
|
+
executor.execute(create_stmt)
|
|
244
|
+
|
|
245
|
+
insert_stmt = InsertStatementNode(
|
|
246
|
+
table=users_table,
|
|
247
|
+
columns=[ColumnNode(name="name"), ColumnNode(name="age")],
|
|
248
|
+
values=[LiteralNode(value="Alice"), LiteralNode(value=30)]
|
|
249
|
+
)
|
|
250
|
+
executor.execute(insert_stmt)
|
|
251
|
+
|
|
252
|
+
select_stmt = SelectStatementNode(
|
|
253
|
+
select_list=[StarNode()],
|
|
254
|
+
from_table=users_table
|
|
255
|
+
)
|
|
256
|
+
print(executor.execute(select_stmt))
|
|
257
|
+
|
|
258
|
+
drop_stmt = DropStatementNode(table=users_table, if_exists=True)
|
|
259
|
+
executor.execute(drop_stmt)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
For more examples, see the `examples/` directory (including `examples/sample_mysql.py`).
|
|
213
263
|
|
|
214
264
|
## Development Setup
|
|
215
265
|
|
|
@@ -249,7 +299,7 @@ poetry run pytest buildaquery/tests
|
|
|
249
299
|
|
|
250
300
|
#### Integration Tests
|
|
251
301
|
|
|
252
|
-
Integration tests require
|
|
302
|
+
Integration tests require PostgreSQL and MySQL databases (and the `mysql-connector-python` driver). Start the test databases using Docker:
|
|
253
303
|
|
|
254
304
|
```bash
|
|
255
305
|
docker-compose up -d
|
|
@@ -283,7 +333,7 @@ poetry run python examples/sample_query.py
|
|
|
283
333
|
|
|
284
334
|
- `buildaquery/abstract_syntax_tree/`: Defines query nodes and AST models.
|
|
285
335
|
- `buildaquery/traversal/`: Base classes for AST traversal (Visitor/Transformer pattern).
|
|
286
|
-
- `buildaquery/compiler/`: Dialect-specific SQL generation (PostgreSQL
|
|
336
|
+
- `buildaquery/compiler/`: Dialect-specific SQL generation (PostgreSQL, SQLite, MySQL).
|
|
287
337
|
- `buildaquery/execution/`: Database connection and execution logic.
|
|
288
338
|
- `tests/`: Exhaustive unit and integration tests.
|
|
289
339
|
- `examples/`: Practical demonstrations of the library.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Build-a-Query
|
|
2
2
|
|
|
3
|
-
A Python-based query builder designed to represent, compile, and execute SQL queries using a dialect-agnostic Abstract Syntax Tree (AST). Supports PostgreSQL and
|
|
3
|
+
A Python-based query builder designed to represent, compile, and execute SQL queries using a dialect-agnostic Abstract Syntax Tree (AST). Supports PostgreSQL, SQLite, and MySQL.
|
|
4
4
|
|
|
5
|
-
## Features
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
7
|
- **Dialect-Agnostic AST**: Build queries using high-level Python objects.
|
|
8
8
|
- **Full DML Support**: Create `SELECT`, `INSERT`, `UPDATE`, and `DELETE` statements.
|
|
@@ -11,7 +11,11 @@ A Python-based query builder designed to represent, compile, and execute SQL que
|
|
|
11
11
|
- **DDL Support**: Basic schema management with `CREATE TABLE` and `DROP TABLE`.
|
|
12
12
|
- **Visitor Pattern Traversal**: Extensible architecture for analysis and compilation.
|
|
13
13
|
- **Secure Compilation**: Automatic parameterization to prevent SQL injection.
|
|
14
|
-
- **Execution Layer**: Built-in support for executing compiled queries via `psycopg` (PostgreSQL) and the standard library `sqlite3` (SQLite).
|
|
14
|
+
- **Execution Layer**: Built-in support for executing compiled queries via `psycopg` (PostgreSQL), `mysql-connector-python` (MySQL), and the standard library `sqlite3` (SQLite).
|
|
15
|
+
|
|
16
|
+
## Dialect Notes
|
|
17
|
+
- MySQL does not support `INTERSECT` / `EXCEPT` or `DROP TABLE ... CASCADE` in this implementation (the compiler raises `ValueError`).
|
|
18
|
+
- SQLite does not support `DROP TABLE ... CASCADE` (the compiler raises `ValueError`).
|
|
15
19
|
|
|
16
20
|
## Installation
|
|
17
21
|
|
|
@@ -28,13 +32,16 @@ pip install buildaquery
|
|
|
28
32
|
- **PostgreSQL database**: A running PostgreSQL instance (version 12+ recommended). You can set this up locally, via Docker, or use a cloud service.
|
|
29
33
|
- Example with Docker: `docker run --name postgres -e POSTGRES_PASSWORD=yourpassword -d -p 5432:5432 postgres:15`
|
|
30
34
|
- `psycopg` (automatically installed as a dependency) - the PostgreSQL adapter for Python.
|
|
35
|
+
- **MySQL database**: A running MySQL instance (version 8.0+ recommended).
|
|
36
|
+
- Example with Docker: `docker run --name mysql -e MYSQL_ROOT_PASSWORD=yourpassword -e MYSQL_DATABASE=buildaquery -d -p 3306:3306 mysql:8.0`
|
|
37
|
+
- `mysql-connector-python` (automatically installed as a dependency) - the MySQL adapter for Python.
|
|
31
38
|
- `python-dotenv` (automatically installed as a dependency) - for loading environment variables from a `.env` file.
|
|
32
39
|
- **SQLite**: Uses Python's standard library `sqlite3` module.
|
|
33
40
|
- **SQLite Version**: SQLite 3.x via Python's `sqlite3` module (the exact SQLite version depends on your Python build; check `sqlite3.sqlite_version` at runtime).
|
|
34
41
|
|
|
35
42
|
### Environment Variables
|
|
36
43
|
|
|
37
|
-
To connect to your PostgreSQL database, set the following environment variables (or use a `.env` file with `python-dotenv`):
|
|
44
|
+
To connect to your PostgreSQL database, set the following environment variables (or use a `.env` file with `python-dotenv`):
|
|
38
45
|
|
|
39
46
|
- `DB_HOST`: PostgreSQL host (e.g., `localhost`)
|
|
40
47
|
- `DB_PORT`: PostgreSQL port (e.g., `5432`)
|
|
@@ -42,14 +49,16 @@ To connect to your PostgreSQL database, set the following environment variables
|
|
|
42
49
|
- `DB_USER`: Database username (e.g., `postgres`)
|
|
43
50
|
- `DB_PASSWORD`: Database password (e.g., `yourpassword`)
|
|
44
51
|
|
|
45
|
-
Example `.env` file:
|
|
46
|
-
```
|
|
47
|
-
DB_HOST=localhost
|
|
48
|
-
DB_PORT=5432
|
|
49
|
-
DB_NAME=buildaquery
|
|
50
|
-
DB_USER=postgres
|
|
51
|
-
DB_PASSWORD=yourpassword
|
|
52
|
-
```
|
|
52
|
+
Example `.env` file:
|
|
53
|
+
```
|
|
54
|
+
DB_HOST=localhost
|
|
55
|
+
DB_PORT=5432
|
|
56
|
+
DB_NAME=buildaquery
|
|
57
|
+
DB_USER=postgres
|
|
58
|
+
DB_PASSWORD=yourpassword
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For MySQL, you can use a connection URL directly in code (e.g., `mysql://user:password@host:3306/dbname`) or set your own environment variables and construct the URL similarly.
|
|
53
62
|
|
|
54
63
|
### For Developers
|
|
55
64
|
|
|
@@ -72,7 +81,7 @@ Activate the virtual environment:
|
|
|
72
81
|
poetry shell
|
|
73
82
|
```
|
|
74
83
|
|
|
75
|
-
## Quick Start
|
|
84
|
+
## Quick Start
|
|
76
85
|
|
|
77
86
|
Here's a simple example of creating a table, inserting data, querying it, and dropping the table. This example uses environment variables for database connection (see Environment Variables section above).
|
|
78
87
|
|
|
@@ -176,7 +185,47 @@ drop_stmt = DropStatementNode(table=users_table, if_exists=True)
|
|
|
176
185
|
executor.execute(drop_stmt)
|
|
177
186
|
```
|
|
178
187
|
|
|
179
|
-
|
|
188
|
+
### MySQL Quick Start
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from buildaquery.execution.mysql import MySqlExecutor
|
|
192
|
+
from buildaquery.abstract_syntax_tree.models import (
|
|
193
|
+
CreateStatementNode, TableNode, ColumnDefinitionNode,
|
|
194
|
+
InsertStatementNode, ColumnNode, LiteralNode,
|
|
195
|
+
SelectStatementNode, StarNode, DropStatementNode
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
executor = MySqlExecutor(connection_info="mysql://root:password@127.0.0.1:3306/buildaquery")
|
|
199
|
+
|
|
200
|
+
users_table = TableNode(name="users")
|
|
201
|
+
create_stmt = CreateStatementNode(
|
|
202
|
+
table=users_table,
|
|
203
|
+
columns=[
|
|
204
|
+
ColumnDefinitionNode(name="id", data_type="INT AUTO_INCREMENT", primary_key=True),
|
|
205
|
+
ColumnDefinitionNode(name="name", data_type="VARCHAR(255)", not_null=True),
|
|
206
|
+
ColumnDefinitionNode(name="age", data_type="INT")
|
|
207
|
+
]
|
|
208
|
+
)
|
|
209
|
+
executor.execute(create_stmt)
|
|
210
|
+
|
|
211
|
+
insert_stmt = InsertStatementNode(
|
|
212
|
+
table=users_table,
|
|
213
|
+
columns=[ColumnNode(name="name"), ColumnNode(name="age")],
|
|
214
|
+
values=[LiteralNode(value="Alice"), LiteralNode(value=30)]
|
|
215
|
+
)
|
|
216
|
+
executor.execute(insert_stmt)
|
|
217
|
+
|
|
218
|
+
select_stmt = SelectStatementNode(
|
|
219
|
+
select_list=[StarNode()],
|
|
220
|
+
from_table=users_table
|
|
221
|
+
)
|
|
222
|
+
print(executor.execute(select_stmt))
|
|
223
|
+
|
|
224
|
+
drop_stmt = DropStatementNode(table=users_table, if_exists=True)
|
|
225
|
+
executor.execute(drop_stmt)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
For more examples, see the `examples/` directory (including `examples/sample_mysql.py`).
|
|
180
229
|
|
|
181
230
|
## Development Setup
|
|
182
231
|
|
|
@@ -214,9 +263,9 @@ Run unit tests for all modules:
|
|
|
214
263
|
poetry run pytest buildaquery/tests
|
|
215
264
|
```
|
|
216
265
|
|
|
217
|
-
#### Integration Tests
|
|
218
|
-
|
|
219
|
-
Integration tests require
|
|
266
|
+
#### Integration Tests
|
|
267
|
+
|
|
268
|
+
Integration tests require PostgreSQL and MySQL databases (and the `mysql-connector-python` driver). Start the test databases using Docker:
|
|
220
269
|
|
|
221
270
|
```bash
|
|
222
271
|
docker-compose up -d
|
|
@@ -250,9 +299,9 @@ poetry run python examples/sample_query.py
|
|
|
250
299
|
|
|
251
300
|
- `buildaquery/abstract_syntax_tree/`: Defines query nodes and AST models.
|
|
252
301
|
- `buildaquery/traversal/`: Base classes for AST traversal (Visitor/Transformer pattern).
|
|
253
|
-
- `buildaquery/compiler/`: Dialect-specific SQL generation (PostgreSQL
|
|
302
|
+
- `buildaquery/compiler/`: Dialect-specific SQL generation (PostgreSQL, SQLite, MySQL).
|
|
254
303
|
- `buildaquery/execution/`: Database connection and execution logic.
|
|
255
|
-
- `tests/`: Exhaustive unit and integration tests.
|
|
304
|
+
- `tests/`: Exhaustive unit and integration tests.
|
|
256
305
|
- `examples/`: Practical demonstrations of the library.
|
|
257
306
|
- `scripts/`: Utility scripts for testing and maintenance.
|
|
258
307
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `abstract_syntax_tree` module defines the data structures used to represent SQL queries as an Abstract Syntax Tree. This representation is agnostic of any specific SQL dialect and serves as the intermediate format that the query builder constructs and the compiler translates into SQL.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Dialect Notes**: The AST is dialect-agnostic and compilers target PostgreSQL, SQLite, and MySQL.
|
|
6
6
|
|
|
7
7
|
## Core Concepts
|
|
8
8
|
|
|
@@ -44,12 +44,22 @@ The initial implementation supports PostgreSQL.
|
|
|
44
44
|
- **Core AST Coverage**: Supports the same AST nodes as PostgreSQL where SQLite syntax allows.
|
|
45
45
|
- **TOP Translation**: Maps `TopClauseNode` to `LIMIT`, with optional implicit `ORDER BY`.
|
|
46
46
|
- **CASCADE Handling**: Raises a `ValueError` when `DropStatementNode.cascade=True`, because SQLite does not support `DROP TABLE ... CASCADE`.
|
|
47
|
+
|
|
48
|
+
### MySQL (`MySqlCompiler`)
|
|
49
|
+
|
|
50
|
+
#### Key Features:
|
|
51
|
+
- **`%s` Placeholders**: Uses MySQL-compatible parameter style.
|
|
52
|
+
- **Core AST Coverage**: Supports the same AST nodes as PostgreSQL where MySQL syntax allows.
|
|
53
|
+
- **TOP Translation**: Maps `TopClauseNode` to `LIMIT`, with optional implicit `ORDER BY`.
|
|
54
|
+
- **Set Operation Limits**: Raises a `ValueError` for `INTERSECT` and `EXCEPT` (unsupported in MySQL).
|
|
55
|
+
- **CASCADE Handling**: Raises a `ValueError` when `DropStatementNode.cascade=True`, because MySQL does not support `DROP TABLE ... CASCADE`.
|
|
47
56
|
|
|
48
57
|
## Usage Example
|
|
49
58
|
|
|
50
59
|
```python
|
|
51
60
|
from buildaquery.compiler.postgres.postgres_compiler import PostgresCompiler
|
|
52
61
|
from buildaquery.compiler.sqlite.sqlite_compiler import SqliteCompiler
|
|
62
|
+
from buildaquery.compiler.mysql.mysql_compiler import MySqlCompiler
|
|
53
63
|
|
|
54
64
|
compiler = PostgresCompiler()
|
|
55
65
|
compiled = compiler.compile(ast_root)
|
|
@@ -61,4 +71,9 @@ sqlite_compiler = SqliteCompiler()
|
|
|
61
71
|
compiled = sqlite_compiler.compile(ast_root)
|
|
62
72
|
print(compiled.sql) # "SELECT * FROM users WHERE id = ?"
|
|
63
73
|
print(compiled.params) # [123]
|
|
64
|
-
|
|
74
|
+
|
|
75
|
+
mysql_compiler = MySqlCompiler()
|
|
76
|
+
compiled = mysql_compiler.compile(ast_root)
|
|
77
|
+
print(compiled.sql) # "SELECT * FROM users WHERE id = %s"
|
|
78
|
+
print(compiled.params) # [123]
|
|
79
|
+
```
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
from buildaquery.compiler.postgres.postgres_compiler import PostgresCompiler
|
|
2
|
+
from buildaquery.compiler.sqlite.sqlite_compiler import SqliteCompiler
|
|
3
|
+
from buildaquery.compiler.mysql.mysql_compiler import MySqlCompiler
|
|
4
|
+
|
|
5
|
+
__all__ = ["PostgresCompiler", "SqliteCompiler", "MySqlCompiler"]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# MySQL Compiler
|
|
2
|
+
|
|
3
|
+
The `MySqlCompiler` translates the AST into MySQL-compatible SQL with `%s` placeholders.
|
|
4
|
+
|
|
5
|
+
## Notes
|
|
6
|
+
|
|
7
|
+
- **Placeholders**: Uses `%s` for parameters (compatible with `mysql-connector-python`).
|
|
8
|
+
- **TOP Translation**: `TopClauseNode` is translated into `LIMIT`, with optional implicit `ORDER BY`.
|
|
9
|
+
- **Unsupported Operations**:
|
|
10
|
+
- `INTERSECT` and `EXCEPT` raise `ValueError` (MySQL does not support them).
|
|
11
|
+
- `DROP TABLE ... CASCADE` raises `ValueError`.
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from buildaquery.compiler.mysql.mysql_compiler import MySqlCompiler
|
|
17
|
+
from buildaquery.abstract_syntax_tree.models import SelectStatementNode, StarNode, TableNode
|
|
18
|
+
|
|
19
|
+
compiler = MySqlCompiler()
|
|
20
|
+
query = SelectStatementNode(select_list=[StarNode()], from_table=TableNode(name="users"))
|
|
21
|
+
compiled = compiler.compile(query)
|
|
22
|
+
|
|
23
|
+
print(compiled.sql) # SELECT * FROM users
|
|
24
|
+
print(compiled.params) # []
|
|
25
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Intentionally left empty to mark mysql as a package.
|