{"id":51130820,"url":"https://github.com/awolverp/rapidquery","last_synced_at":"2026-06-25T12:01:35.102Z","repository":{"id":353782448,"uuid":"1220849907","full_name":"awolverp/rapidquery","owner":"awolverp","description":"RapidQuery is the fastest, full-feature, and easy-to-use Python SQL query builder written in Rust.","archived":false,"fork":false,"pushed_at":"2026-04-25T13:29:41.000Z","size":628,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-25T15:20:33.686Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awolverp.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-25T12:21:18.000Z","updated_at":"2026-04-25T14:35:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/awolverp/rapidquery","commit_stats":null,"previous_names":["awolverp/rapidquery"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/awolverp/rapidquery","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awolverp%2Frapidquery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awolverp%2Frapidquery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awolverp%2Frapidquery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awolverp%2Frapidquery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awolverp","download_url":"https://codeload.github.com/awolverp/rapidquery/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awolverp%2Frapidquery/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34773843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-25T12:01:34.107Z","updated_at":"2026-06-25T12:01:35.095Z","avatar_url":"https://github.com/awolverp.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RapidQuery\n__*RapidQuery: High-Performance SQL Query Builder for Python*__\n\nRapidQuery is a powerful SQL query builder library designed for Python, combining the simplicity of Python with the raw speed of **Rust**. Build complex SQL queries effortlessly and efficiently, with a library that prioritizes both performance and ease of use.\n\n- [**Installation**](#install)\n- [**Why RapidQuery?**](#why-rapidquery)\n- [**Supported Backends**](#backends)\n- [**Usage**](#usage)\n- [**Performance**](#performance)\n- [**Known Issues**](#known-issues)\n- [**Supported Platforms**](#supported-platforms)\n- [**License**](#license)\n\n## Install\n\nYou can use **PIP**:\n```bash\npip3 install rapidquery\n```\n\nOr you can use **UV** (recommended):\n```bash\nuv add rapidquery\n```\n\n## Why RapidQuery?\n**Features**:\n- **🧶 Thread safe**: It's completely thread-safe and uses locks in internal to prevent concurrency problems.\n- **⚡ Blazing High Performance**: Leveraging the power of Rust under the hood, RapidQuery ensures your query building process is as fast as possible.\n- 🛡️ **SQL Injection Protection**: Built-in security measures to prevent SQL injection attacks by default.\n- 📝 **Intuitive Pythonic API**: Write clean, readable code with an API that feels natural to Python developers.\n- 🔥 **Built on Solid Foundations**: RapidQuery is built with **Rust** and powered by the robust **SeaQuery** crate, bringing enterprise-grade reliability and performance to your Python applications.\n\n\u003e **Why RapidQuery Was Created** \\\n\u003e In a landscape filled with SQL libraries, we noticed a critical gap: **performance was often an afterthought**. That's why we built RapidQuery with speed as our primary and enduring focus.\n\n## Backends\nRapidQuery supports `PostgreSQL`, `MySQL`, and `SQLite`. These are referred to as `backend`s. When building SQL statements, you must specify your target backend.\n\n## Usage\n\n1. Core Concepts\n    1. [**Value**](#value)\n    2. [**Expr**](#expr)\n    3. [**Statement Builders**](#statement-builders)\n2. Query Statements\n    1. [**Query Select**](#query-select)\n    2. [**Query Insert**](#query-insert)\n    3. [**Query Update**](#query-update)\n    4. [**Query Delete**](#query-delete)\n    5. [**Query With**](#query-with)\n3. More About Queries\n    1. [**Custom Function**](#custom-functions)\n4. Schema Statements\n    1. [**Table Create**](#table-create)\n    2. [**Table Alter**](#table-alter)\n    3. [**Table Drop**](#table-drop)\n    4. [**Table Rename**](#table-rename)\n    5. [**Table Truncate**](#table-truncate)\n    8. [**Index Create**](#index-create)\n    9. [**Index Drop**](#index-drop)\n5. Advanced Usage\n    1. [**More About Column References**](#more-about-column-references)\n    2. [**More About TableName**](#more-about-tablename)\n    3. [**More About Expr**](#more-about-expr)\n\n### Core Concepts\n#### Value\nBridges Python types, Rust types, and SQL types for seamless data conversion.\n\nThis class handles validation, adaptation, and conversion between different\ntype systems used in the application stack.\n\n\u003e [!NOTE]\\\n\u003e this class is immutable and frozen.\n\n\u003e [!TIP]\\\n\u003e **Important**: `Value` is lazy. This means it keeps your value and never converts it to Rust and then SQL until needed.\n\n#### Expr\nRepresents a SQL expression that can be built into SQL code.\n\nThis class provides a fluent interface for constructing complex SQL expressions\nin a database-agnostic way. It supports arithmetic operations, comparisons,\nlogical operations, and database-specific functions.\n\nThe class automatically handles SQL injection protection and proper quoting\nwhen building the final SQL statement.\n\n\u003e [!NOTE]\\\n\u003e `Expr` is immutable, so by calling each method you will give a new instance\nof it which includes new change(s).\n\n**Basic**\n```python\nimport rapidquery as rp\n\nrp.Expr(25)                         # -\u003e 25  (literal value)\nrp.Expr(\"Hello\")                    # -\u003e 'Hello'  (literal value)\nrp.Expr(rq.Value('World'))          # -\u003e 'World'  (literal value)\n\nrp.Expr.col(\"id\")                             # -\u003e \"id\" (column reference)\nrp.Expr.col(\"users.name\")                     # -\u003e \"users\".\"name\" (column reference)\nrp.Expr(rq.ColumnRef(\"name\", table=\"users\"))  # -\u003e \"users\".\"name\" (column reference)\n```\n\n**Comparisons**\n```python\nrq.Expr.col(\"status\") == \"active\"  # -\u003e \"status\" == 'active'\nrq.Expr.col(\"age\") \u003e 16           # -\u003e \"age\" \u003e 16\n\n# Note that `rq.all` is different from built-in `all`\nrq.all(\n    rq.Expr.col(\"age\") \u003e= 18,\n    rq.Expr.col(\"subscription\").is_null(), # same as rq.Expr.col(\"subscription\").is_(Expr.null())\n    rq.Expr.col(\"status\").in_([\"pending\", \"approved\", \"active\"])\n)    # -\u003e \"age\" \u003e= 18 AND \"subscription\" IS NULL AND \"status\" IN ('pending', 'approved', 'active')\n\n# Note that `rq.any` is different from built-in `any`\nrq.any(\n    rq.Expr.col(\"is_admin\").is_(True),\n    rq.Expr.col(\"is_moderator\").is_not_null(), # same as rq.Expr.col(\"subscription\").is_not(Expr.null())\n    rq.Expr.col(\"price\").between(10.00, 50.00)\n)    # -\u003e \"is_admin\" IS TRUE OR \"is_moderator\" IS NOT NULL OR \"price\" BETWEEN 10.00 AND 50.00\n```\n\n**Best Practices**\n- Always use `Expr.col()` for column references: This ensures proper quoting for your target database\n```python\n# Column reference (properly quoted identifier)\nrq.Expr.col(\"user_name\")  # → \"user_name\"\n\n# String literal (value)\nrq.Expr(\"user_name\")      # → 'user_name'\n```\n\n- Use `rapidquery.all()` and `rapidquery.any()` for logical combinations: More readable than chaining `\u0026` and `|` operators\n```python\n# Good\nall(condition1, condition2, condition3)\n   \n# Less readable\ncondition1 \u0026 condition2 \u0026 condition3\n```\n\n- Be careful with `Expr.custom()`: It bypasses all safety checks\n```python\n# Dangerous - vulnerable to SQL injection\nuser_input = \"'; DROP TABLE users; --\"\nExpr.custom(f\"name = '{user_input}'\")\n\n# Safe\nExpr.col(\"name\") == user_input\n```\n\n#### Statement Builders\nStatements are divided into 2 categories: `QueryStatement`, and `SchemaStatement`.\n\nSome statements like `Select`, `Update`, `Delete`, `Insert`, ... are `QueryStatement`.\nOther statements like `Table`, `AlterTable`, `Index`, ... are `SchemaStatement`.\n\n`QueryStatement` class interface is:\n```python\nclass QueryStatement:\n    \"\"\"Subclass of query statements.\"\"\"\n\n    def build(self, backend: _BackendName, /) -\u003e tuple[str, tuple[Value, ...]]:\n        \"\"\"Build the SQL statement with parameter values.\"\"\"\n        ...\n\n    def to_sql(self, backend: _BackendName, /) -\u003e str:\n        \"\"\"\n        Build a SQL string representation.\n\n        **This method is unsafe and can cause SQL injection.** use `.build()` method instead.\n        \"\"\"\n        ...\n```\n\n`SchemaStatement` class interface is:\n```python\nclass SchemaStatement:\n    \"\"\"Subclass of schema statements.\"\"\"\n\n    def to_sql(self, backend: _BackendName, /) -\u003e str:\n        \"\"\"Build a SQL string representation.\"\"\"\n        ...\n```\n\n### Query Select\nUse `rapidquery.SelectStatement` type to generate `SELECT` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = (\n    rq.SelectStatement()\n    .columns(\"character\", \"fonts.name\")\n    .from_table(\"characters\")\n    .join(\"fonts\", rq.Expr.col(\"characters.font_id\") == rq.Expr.col(\"fonts.id\"), \"LEFT\")\n    .where(rq.Expr.col(\"size_w\").in_([3, 4]))\n    .where(rq.Expr.col(\"characters\").like(\"A%\"))\n)\nprint(stmt.to_sql(\"postgres\"))\n# SELECT \"character\" AS \"character\", \"fonts\".\"name\" AS \"name\" FROM \"characters\"\n# LEFT JOIN \"fonts\" ON \"characters\".\"font_id\" = \"fonts\".\"id\"\n# WHERE \"size_w\" IN (3, 4) AND \"characters\" LIKE 'A%'\n\nprint(stmt.to_sql(\"mysql\"))\n# SELECT `character` AS `character`, `fonts`.`name` AS `name` FROM `characters`\n# LEFT JOIN `fonts` ON `characters`.`font_id` = `fonts`.`id`\n# WHERE `size_w` IN (3, 4) AND `characters` LIKE 'A%'\n\nprint(stmt.to_sql(\"sqlite\"))\n# SELECT \"character\" AS \"character\", \"fonts\".\"name\" AS \"name\" FROM \"characters\"\n# LEFT JOIN \"fonts\" ON \"characters\".\"font_id\" = \"fonts\".\"id\" \n# WHERE \"size_w\" IN (3, 4) AND \"characters\" LIKE 'A%'\n```\n\n### Query Insert\nUse `rapidquery.InsertStatement` type to generate `INSERT` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = (\n    rq.InsertStatement(\"glyph\")\n    .values(aspect=3.14, image=\"A4\")\n    .on_conflict(rq.OnConflict(\"id\").do_update(\"image\"))\n)\n\nprint(stmt.to_sql(\"postgres\"))\n# INSERT INTO \"glyph\" (\"aspect\", \"image\") VALUES (3.14, 'A4')\n# ON CONFLICT (\"id\") DO UPDATE SET \"image\" = \"excluded\".\"image\"\n# \nprint(stmt.to_sql(\"mysql\"))\n# INSERT INTO `glyph` (`aspect`, `image`) VALUES (3.14, 'A4')\n# ON DUPLICATE KEY UPDATE `image` = VALUES(`image`)\n\nprint(stmt.to_sql(\"sqlite\"))\n# INSERT INTO \"glyph\" (\"aspect\", \"image\") VALUES (3.14, 'A4')\n# ON CONFLICT (\"id\") DO UPDATE SET \"image\" = \"excluded\".\"image\"\n```\n\n### Query Update\nUse `rapidquery.UpdateStatement` type to generate `UPDATE` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = (\n    rq.UpdateStatement(\"glyph\")\n    .values(aspect=1.23, image=\"123\")\n    .where(rq.Expr.col(\"id\") == 1)\n)\n\nprint(stmt.to_sql(\"postgres\"))\n# UPDATE \"glyph\" SET \"aspect\" = 1.23, \"image\" = '123' WHERE \"id\" = 1\n\nprint(stmt.to_sql(\"mysql\"))\n# UPDATE `glyph` SET `aspect` = 1.23, `image` = '123' WHERE `id` = 1\n\nprint(stmt.to_sql(\"sqlite\"))\n# UPDATE \"glyph\" SET \"aspect\" = 1.23, \"image\" = '123' WHERE \"id\" = 1\n```\n\n### Query Delete\nUse `rapidquery.DeleteStatement` type to generate `DELETE` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = rq.DeleteStatement(\"glyph\").where(\n    rq.any(\n        rq.Expr.col(\"id\") \u003c 1,\n        rq.Expr.col(\"id\") \u003e 10,\n    )\n)\n\nprint(stmt.to_sql(\"postgres\"))\n# DELETE FROM \"glyph\" WHERE \"id\" \u003c 1 OR \"id\" \u003e 10\n\nprint(stmt.to_sql(\"mysql\"))\n# DELETE FROM `glyph` WHERE `id` \u003c 1 OR `id` \u003e 10\n\nprint(stmt.to_sql(\"sqlite\"))\n# DELETE FROM \"glyph\" WHERE \"id\" \u003c 1 OR \"id\" \u003e 10\n```\n\n### Query With\nWe have two types here: `rapidquery.WithClause` and `rapidquery.WithQuery`.\n\n```txt\n         WithQuery\n             |\n|------------------------|\nWITH [... CTEs ...] QUERY\n|------------------|\n         |\n     WithClause\n```\n\n\nAs you can see, `rapidquery.WithClause` includes common table expressions (CTEs),\nand `rapidquery.WithQuery` includes `rapidquery.WithClause` and the final query.\n\n```python\nimport rapidquery as rq\n\nclause = (\n    rq.WithClause()\n    .cte(\n        \"users_count\",\n        (\n            rq.UpdateStatement(\"users\")\n            .values(amount=rq.Expr.col(\"amount\") + 10)\n            .where(rq.Expr.col(\"id\") \u003e 50)\n            .returning(rq.Returning(rq.Expr.val(1)))\n        ),\n    )\n    .cte(\n        \"teams_count\",\n        (\n            rq.UpdateStatement(\"teams\")\n            .values(amount=rq.Expr.col(\"amount\") + 10)\n            .where(rq.Expr.col(\"id\") \u003e 50)\n            .returning(rq.Returning(rq.Expr.val(1)))\n        ),\n    )\n)\n\nusers_count_select = rq.SelectStatement(rq.Func.count(rq.Expr.asterisk())).from_table(\"users_count\")\nteams_count_select = rq.SelectStatement(rq.Func.count(rq.Expr.asterisk())).from_table(\"teams_count\")\n\nquery: WithQuery = clause.query(\n    rq.SelectStatement(\n        users_count_select.label(\"users\"),\n        teams_count_select.label(\"teams\"),\n    )\n)\nquery.to_sql(\"postgres\")\n# WITH \n#   \"users_count\" AS (\n#       UPDATE \"users\" SET \"amount\" = \"amount\" + 10 WHERE \"id\" \u003e 50 RETURNING 1\n#   ) ,\n#   \"teams_count\" AS (\n#       UPDATE \"teams\" SET \"amount\" = \"amount\" + 10 WHERE \"id\" \u003e 50 RETURNING 1\n#   )\n#   SELECT\n#       (SELECT COUNT(*) FROM \"users_count\") AS \"users\",\n#       (SELECT COUNT(*) FROM \"teams_count\") AS \"teams\"\n```\n\n### Custom Functions\nFor working with functions in RapidQuery, you have to use `Func` class.\nA lot of functions such as `SUM`, `AVG`, `MD5`, ... is ready to use. For example:\n\n```python\nstmt = rq.SelectStatement(rq.Func.sum(rq.Expr.col(\"amount\")))\nstmt.to_sql(\"postgres\")\n# SELECT SUM(\"amount\")\n```\n\nBut for functions not provided by the library, you can define custom functions.\nCustom functions can be defined using the `Func` constructor:\n\n```python\nstmt = rq.SelectStatement(rq.Func(\"CUSTOM\", 1, 'hello'))\nstmt.to_sql(\"postgres\")\n# SELECT CUSTOM(1, 'hello')\n```\n\n### Table Create\n`rapidquery.Table` represents a complete database table definition. Use it to generate `CREATE TABLE` statements.\n\n```python\nimport rapidquery as rq\n\ncharacters = rq.Table(\n    \"characters\",\n    rq.Column(\"id\", rq.sqltypes.Integer(), primary_key=True, auto_increment=True),\n    rq.Column(\"font_size\", rq.sqltypes.Integer(), nullable=False),\n    rq.Column(\"character\", rq.sqltypes.String(), nullable=False),\n    rq.Column(\"size_w\", rq.sqltypes.Integer(), nullable=False),\n    rq.Column(\"size_h\", rq.sqltypes.Integer(), nullable=False),\n    rq.Column(\"font_id\", rq.sqltypes.Integer(), default=None),\n    rq.ForeignKey([\"font_id\"], [\"fonts.id\"], on_delete=\"CASCADE\", on_update=\"CASCADE\"),\n    rq.Index(\"idx_character\", [\"character\"]),\n    if_not_exists=True,\n)\n\nprint(characters.to_sql(\"postgresql\"))\n# CREATE TABLE IF NOT EXISTS \"characters\" (\n#   \"id\" serial PRIMARY KEY,\n#   \"font_size\" integer NOT NULL,\n#   \"character\" varchar NOT NULL,\n#   \"size_w\" integer NOT NULL,\n#   \"size_h\" integer NOT NULL,\n#   \"font_id\" integer DEFAULT NULL,\n#   FOREIGN KEY (\"font_id\") REFERENCES \"fonts\" (\"id\") ON DELETE CASCADE ON UPDATE CASCADE\n# );\n# CREATE INDEX IF NOT EXISTS \"idx_character\" ON \"characters\" (\"character\")\n```\n\n### Table Alter\nUse `rapidquery.AlterTable` type to generate `ALTER TABLE` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = rq.AlterTable(\n    \"fonts\",\n    [\n        rq.AlterTableAddColumnOption(\n            rq.Column(\n                \"new_col\",\n                rq.sqltypes.Integer(),\n                nullable=False,\n                default=100,\n            )\n        ),\n        rq.AlterTableRenameColumnOption(\"hello\", \"world\"),\n    ],\n)\nprint(stmt.to_sql(\"mysql\"))\n# ALTER TABLE `fonts` ADD COLUMN `new_col` int NOT NULL DEFAULT 100,\n# RENAME COLUMN `hello` TO `world`\n```\n\n### Table Drop\nUse `rapidquery.DropTable` type to generate `DROP TABLE` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = rq.DropTable(\"glyph\", if_exists=True)\nprint(stmt.to_sql(\"mysql\"))\n# DROP TABLE IF EXISTS `glyph`\n```\n\n### Table Rename\nUse `rapidquery.RenameTable` type to generate `RENAME TABLE` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = rq.RenameTable(\"old\", \"new\")\n\nprint(stmt.to_sql(\"sqlite\"))\n# ALTER TABLE \"old\" RENAME TO \"new\"\n\nprint(stmt.to_sql(\"mysql\"))\n# RENAME TABLE `old` TO `new`\n```\n\n### Table Truncate\nUse `rapidquery.TruncateTable` type to generate `TRUNCATE TABLE` statements.\n\n```python\nimport rapidquery as rq\n\nstmt = rq.TruncateTable(\"old\")\n\nprint(stmt.to_sql(\"mysql\"))\n# TRUNCATE TABLE `old`\n```\n\n### Index Create\n\n```python\nimport rapidquery as rq\n\nidx = rq.Index(\"idx_glyph_aspect\", [\"aspect\"], \"glyph\")\n\nprint(idx.to_sql(\"postgres\"))\n# CREATE INDEX \"idx_glyph_aspect\" ON \"glyph\" (\"aspect\")\n```\n\n### Index Drop\nUse `rapidquery.DropIndex` type to generate `DROP INDEX` statements.\n\n```python\nimport rapidquery as rq\n\nidx = rq.DropIndex(\"idx_glyph_aspect\", \"glyph\")\n\nprint(idx.to_sql(\"postgres\"))\n# DROP INDEX \"idx_glyph_aspect\"\n```\n\n### More About Column Reference\nLet's learn some tricks about column references.\n\nIn RapidQuery, we have something called `ColumnRef`, which represents a reference to a database column with optional table and schema qualification.\n\n\u003e This type is a final type, which means you cannot use it as subclass.\n\nIn generating statements, we have a lot of situations that you need to work with column references.\n\n**❗ The Trick** \\\nFor the parameters which accept column references, you have 4 ways:\n\n1. Use `ColumnRef`:\n```python\ncol_ref = rq.ColumnRef(\"id\", \"characters\")\n# OR\ncol_ref = rq.ColumnRef.parse(\"characters.id\")\n\nstmt = rq.SelectStatement().columns(col_ref)\n# SELECT \"characters\".\"id\" AS \"id\"\n```\n\n2. Use `str`: The easiest way\n```python\nstmt = rq.SelectStatement().columns(\"characters.id\")\n# SELECT \"characters\".\"id\" AS \"id\"\n```\n\n3. Use `__column_ref__` property: developer-friendly and expandable way.\n```python\nclass IdColumnProperty:\n    @property\n    def __column_ref__(self):\n        # Can return ColumnRef or str\n        return \"characters.id\"\n\nclass IdColumnClassVar:\n    __column_ref__ = \"characters.id\"\n\nstmt = rq.SelectStatement().columns(IdColumnProperty())\n# SELECT \"characters\".\"id\" AS \"id\"\n\nstmt = rq.SelectStatement().columns(IdColumnClassVar)\n# SELECT \"characters\".\"id\" AS \"id\"\n```\n\n4. Use `Column`: It's possible because `Column` has `__column_ref__` property.\n```python\nid = Column(\"id\", rq.Integer())\n\nstmt = rq.SelectStatement().columns(id)\n# SELECT \"id\" AS \"id\"\n```\n\n\n### More About TableName\nLet's learn some tricks about table name.\n\nIn RapidQuery, we have something called `TableName`, which represents a table name reference with optional schema, database, and alias.\n\n\u003e This type is a final type, which means you cannot use it as subclass.\n\nIn generating statements, we have situations that you need to specify table name.\n\n**❗ The Trick** \\\nFor the parameters which accept table name, you have 4 ways:\n\n1. Use `TableName`:\n```python\ntbl = rq.TableName(\"users\", schema=\"archive\")\n# OR\ntbl = rq.TableName.parse(\"archive.users\")\n\nstmt = rq.DeleteStatement(tbl)\n# DELETE FROM \"archive\".\"users\"\n```\n\n2. Use `str`: The easiest way\n```python\nstmt = rq.DeleteStatement(\"archive.users\")\n# DELETE FROM \"archive\".\"users\"\n```\n\n3. Use `__table_name__` property: developer-friendly and expandable way.\n```python\nclass UsersProperty:\n    @property\n    def __table_name__(self):\n        # Can return TableName or str\n        return \"archive.users\"\n\n\nclass UsersClassVar:\n    __table_name__ = \"archive.users\"\n\n\nstmt = rq.DeleteStatement(UsersProperty())\n# DELETE FROM \"archive\".\"users\"\n\nstmt = rq.DeleteStatement(UsersClassVar)\n# DELETE FROM \"archive\".\"users\"\n```\n\n4. Use `Table`: It's possible because `Table` has `__table_name__` property.\n```python\nusers = Table(\n    \"archive.users\",\n    ...\n)\n\nstmt = rq.DeleteStatement(users)\n# DELETE FROM \"archive\".\"users\"\n```\n\n### More About Expr\nYou learned [here](#expr) about `Expr` type.\n\n**❗ The Trick** \\\nThis 2 tricks are notable and very good to know.\n\n1. First, like `ColumnRef` and `TableName`, `Expr` supports `__expr__` property, which should always return `Expr`.\n\n```python\nclass TextClause:\n    def __init__(self, expr: str) -\u003e None:\n        self.expr = expr\n\n    @property\n    def __expr__(self) -\u003e rq.Expr:\n        return rq.Expr.custom(self.expr)\n\n\nstmt = rq.SelectStatement(TextClause(\"WOW!\"))\n# SELECT WOW!\n```\n\n2. Second, same as `ColumnRef`, `Expr` also supports `__column_ref__` property.\n\n## Performance\n### Benchmarks\nBenchmarks run on *Linux 6.18.12-1-MANJARO x86_64* with CPython 3.14. Your results may vary.\n\nIterations per test: 100,000 \\\nPython version: 3.14.3\n\n```\n📊 SELECT Query Benchmark\n----------------------------------------------------------------------\nLibrary              Time (ms)       vs Fastest      Status\n----------------------------------------------------------------------\nRapidQuery               245.44     1.00x (FASTEST) 🏆\nPyPika                  4327.18     17.63x slower\nSQLAlchemy              8818.33     35.93x slower\n----------------------------------------------------------------------\n\n📊 INSERT Query Benchmark\n----------------------------------------------------------------------\nLibrary              Time (ms)       vs Fastest      Status\n----------------------------------------------------------------------\nRapidQuery               640.63     1.00x (FASTEST) 🏆\nPyPika                  4655.51     7.27x slower\nSQLAlchemy              7085.74     11.06x slower\n----------------------------------------------------------------------\n\n📊 UPDATE Query Benchmark\n----------------------------------------------------------------------\nLibrary              Time (ms)       vs Fastest      Status\n----------------------------------------------------------------------\nRapidQuery               557.21     1.00x (FASTEST) 🏆\nPyPika                  4488.96     8.06x slower\nSQLAlchemy             11839.85     21.25x slower\n----------------------------------------------------------------------\n\n📊 DELETE Query Benchmark\n----------------------------------------------------------------------\nLibrary              Time (ms)       vs Fastest      Status\n----------------------------------------------------------------------\nRapidQuery               441.38     1.00x (FASTEST) 🏆\nPyPika                  4517.16     10.23x slower\nSQLAlchemy              7924.52     17.95x slower\n----------------------------------------------------------------------\n```\n\n## Known Issues\n### Unmanaged Rust panic output in building SQL\nThe library may encounter errors during SQL query construction, which are correctly raised as *RuntimeError* exceptions. For instance, this occurs when using a function that isn't supported by your target database. **While this error-raising behavior is intentional and logical, the issue is that unmanaged Rust panic information is also printed to stderr**. Currently, there is no way to suppress or manage this panic output. We are working to resolve this problem as much as possible in future updates.\n\n```python\n\u003e\u003e\u003e import rapidquery as rq\n\u003e\u003e\u003e stmt = rq.TruncateTable(\"users\")\n\u003e\u003e\u003e print(stmt.to_sql(\"sqlite\"))\n\nthread '\u003cunnamed\u003e' (14206) panicked at sea-query-0.32.7/src/backend/sqlite/table.rs:58:9:\nSqlite doesn't support TRUNCATE statement\nTraceback (most recent call last):\n  File \"\u003cpython-input-3\u003e\", line 1, in \u003cmodule\u003e\n    print(stmt.to_sql(\"sqlite\"))\n          ~~~~~~~~~~~^^^^^^^^^^\nRuntimeError: build failed\n```\n\n### Missing `__init__` Calls\nIf a RapidQuery object is instantiated without calling its `__init__` method (e.g., via certain serialization tricks or `__new__` alone), the internal Rust pointer will be null. Accessing methods on such objects will cause an unmanaged Rust panic. Always use the provided constructors.\n\n### Join conditions are not optional\nCurrently, `JOIN` operations require an explicit ON or USING condition.\n\n## Supported Platforms\n\nPre-built wheels are available for the following platforms and Python interpreters:\n\n### Linux (manylinux)\n\n| Architecture | Python Versions |\n|---|---|\n| x86_64 | 3.10 – 3.14, 3.14t, PyPy 3.11, GraalPy 3.11/3.12 |\n| i686 | 3.10 – 3.14, 3.14t, PyPy 3.11 |\n| aarch64 | 3.10 – 3.14, 3.14t, PyPy 3.11, GraalPy 3.11/3.12 |\n| armv7 | 3.10 – 3.14, 3.14t |\n| s390x | 3.10 – 3.14, 3.14t |\n| ppc64le | 3.10 – 3.14, 3.14t |\n| riscv64 | 3.10 – 3.14, 3.14t |\n\n### Linux (musllinux 1.1)\n\n| Architecture | Python Versions |\n|---|---|\n| x86_64 | 3.10 – 3.14, 3.14t, PyPy 3.11 |\n| aarch64 | 3.10 – 3.14, 3.14t, PyPy 3.11 |\n| armv7 | 3.10 – 3.14, 3.14t, PyPy 3.11 |\n\n### Windows\n\n| Architecture | Python Versions |\n|---|---|\n| x64 | 3.10 – 3.14, 3.14t |\n| x86 | 3.10 – 3.14, 3.14t |\n\n### macOS\n\n| Architecture | Python Versions |\n|---|---|\n| x86_64 | 3.10 – 3.14, 3.13t, 3.14t, PyPy 3.11 |\n| aarch64 (Apple Silicon) | 3.10 – 3.14, 3.13t, 3.14t, PyPy 3.11 |\n\nA source distribution (sdist) is also published for platforms not listed above, which requires a Rust nightly toolchain to build from source.\n\n## TODO\n- [x] Write tests\n- [x] Update \u0026 automate workflows\n- [x] Write CTE\n- [x] Complete README.md\n- [x] Bump version to 0.1.0\n- [ ] Complete backend-only functions\n\n## License\nThis repository is licensed under the [GNU GPLv3 License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawolverp%2Frapidquery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawolverp%2Frapidquery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawolverp%2Frapidquery/lists"}