An injection-safe SQL query builder. Pure Python, zero dependencies.
Concatenating SQL is how injection happens. larzsql builds SELECT/INSERT/UPDATE/
DELETE where every value becomes a bound parameter (never interpolated) and
every table/column name is validated as a plain identifier - so a value or a name
can't smuggle in SQL. You get back (sql, params) ready for your DB-API driver.
from larzsql import select, insert, update, delete
select("id", "name").from_("users").where(active=True, age__gte=18) \
.order_by("-created").limit(10).build()
# ('SELECT id, name FROM users WHERE active = ? AND age >= ? ORDER BY created DESC LIMIT 10',
# [True, 18])
insert("users").values(name="Ada", email="a@b.com").build()
# ('INSERT INTO users (name, email) VALUES (?, ?)', ['Ada', 'a@b.com'])- Injection-safe by construction. Values are always bound parameters - even a
"1; DROP TABLE users; --"value ends up inparams, never in the SQL text - and identifiers are validated against a strict pattern, sofrom_("users; DROP ...")raises instead of executing. - Fluent and complete.
wherewith Django-style lookups (age__gte,id__in,deleted__isnull) or raw fragments,join/left_join,order_by(-colfor DESC),limit/offset, plus INSERT/UPDATE/DELETE. - Driver-agnostic.
build(paramstyle="?")for sqlite or"%s"for psycopg2/MySQL. - Not an ORM. It builds strings + params; you run them. Zero dependencies, pairs with larzdb / larzmigrate.
pip install larzsqlfrom larzsql import select, insert, update, delete
select("*").from_("orders").where(status__in=["paid", "shipped"]).build()
select("u.id", "o.total").from_("users").left_join("orders", "orders.user_id = users.id").build()
update("users").set(active=False).where(id=5).build()
delete("sessions").where(expires__lt=now).build()
sql, params = select("*").from_("t").where(id=1).build(paramstyle="%s")
cursor.execute(sql, params)python -m unittest discover -s tests -v # 17 tests incl. injection safetyOne of 30+ pure-Python, zero-dependency libraries at github.com/larz-scripter.
MIT (c) larz-scripter