惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
云风的 BLOG
云风的 BLOG
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
GbyAI
GbyAI
C
Check Point Blog
M
MIT News - Artificial intelligence
T
The Blog of Author Tim Ferriss
Jina AI
Jina AI
博客园 - 【当耐特】
U
Unit 42
月光博客
月光博客
腾讯CDC
Y
Y Combinator Blog
小众软件
小众软件
博客园_首页
Last Week in AI
Last Week in AI
酷 壳 – CoolShell
酷 壳 – CoolShell
The GitHub Blog
The GitHub Blog
博客园 - 聂微东
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
T
Tailwind CSS Blog

Hacker News: Front Page

SPICE simulation → oscilloscope → verification with Claude Code — Lucas Gerads Introducing Claude Opus 4.7 Qwen Studio The Future of Everything is Lies, I Guess: Where Do We Go From Here? GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis Ancient DNA reveals pervasive directional selection across West Eurasia [pdf] AI cybersecurity is not proof of work Moving a large-scale metrics pipeline from StatsD to OpenTelemetry / Prometheus GitHub - Nightmare-Eclipse/RedSun: The Red Sun vulnerability repository GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. A Better Ludum Dare; Or, How to Ruin a Legacy GitHub - macOS26/Agent: Any AI, replaces Claude Code, Cursor, OpenClaw. Over 18 LLM providers (Claude, OpenAI, Gemini, Ollama, Zai, HF, Qwen) wired into a native Mac app that writes code, builds Xcode projects, bumps versions, manages git, automates Safari, use AppleScript, JS or Accessibility, extend Agent! w/ MCP Servers, run tasks from your iPhone via Messages. YouTube now lets you turn off Shorts I Made a Terminal Pager Burgers | マクドナルド公式 Commands — HackerNews CLI documentation ChatGPT for Excel PiCore - Raspberry Pi Port of Tiny Core Linux Live Nation illegally monopolized ticketing market, jury finds Google Broke Its Promise to Me. Now ICE Has My Data. Founding Engineer at Adaptional | Y Combinator CRISPR takes important step toward silencing Down syndrome’s extra chromosome GitHub - saffron-health/libretto: The AI toolkit for building reliable browser automations US v. Heppner (S.D.N.Y. 2026) no attorney-client privilege for AI chats [pdf] Unexpected €54k billing spike in 13 hours: Firebase browser key without API restrictions used for Gemini requests Fragments: April 14 Cal.com Goes Closed Source: Why AI Security Is Forcing Our Decision | Cal.com - Scheduling Software for Online Bookings Laravel raised money and now injects ads directly into your agent Codex Hacked a Samsung TV
GitHub - enumura1/py-sql-cleaner: Find, format, and safel...
enumura · 2026-05-29 · via Hacker News: Front Page

py-sql-cleaner is a CLI tool for finding, formatting, and extracting SQL embedded in Python files.

It is built for Python codebases where long SQL queries are written directly inside triple-quoted Python strings. The current MVP uses SQLGlot for formatting, defaults to SQLGlot's generic dialect, and can format with database-specific dialects that this project has explicitly enabled via --dialect.

query = """
select user_id, updated_at
from users
qualify row_number() over(partition by user_id order by updated_at desc)=1
"""

py-sql-cleaner can format that SQL in place, or extract it into an external .sql file.

py-sql-cleaner is an early MVP. It uses SQLGlot internally for best-effort SQL formatting. It does not connect to databases and does not execute SQL. Dialect support means SQLGlot parser/formatter mode selection, not exhaustive database validation. With -d redshift, Redshift command-style statements such as COPY and UNLOAD are preserved rather than reformatted to avoid changing load/export options.

Note

py-sql-cleaner is conservative by default: f-strings, Jinja-like templates, and runtime placeholders are detected but skipped instead of being rewritten.

Features

  • Format SQL embedded in Python triple-quoted strings
  • Extract embedded SQL into external .sql files
  • Replace embedded SQL strings with file references
  • Detect common SQL variable names such as sql, query, *_sql, and *_query
  • Skip unsafe blocks, including f-strings, Jinja-like templates, and runtime placeholders, by default
  • Support explicit dialect selection with --dialect / -d
  • Support check mode for CI
  • Support dry-run mode before rewriting files

Installation

Install py-sql-cleaner from PyPI:

pip install py-sql-cleaner

Or install it as an isolated CLI tool with pipx:

pipx install py-sql-cleaner

Release archives and wheels are also attached to GitHub Releases.

You can also run it without installing:

uvx py-sql-cleaner --help

Quick Start

  1. List embedded SQL blocks:

    py-sql-cleaner list jobs/load_users.py
  2. Preview formatting changes:

    py-sql-cleaner format jobs/load_users.py --dry-run
  3. Format embedded SQL in place:

    py-sql-cleaner format jobs/load_users.py
  4. Format with a database-specific dialect:

    py-sql-cleaner format jobs/load_users.py -d redshift

    Currently enabled dialects are generic, mysql, postgres, and redshift.

  5. Extract embedded SQL into .sql files:

    py-sql-cleaner extract jobs/load_users.py --out-dir sql
  6. Check formatting for CI:

    py-sql-cleaner check jobs/load_users.py

Example

Before:

query = """
select user_id, updated_at
from users
qualify row_number() over(partition by user_id order by updated_at desc)=1
"""

After py-sql-cleaner format jobs/load_users.py:

query = """
SELECT
  user_id,
  updated_at
FROM users
QUALIFY
  ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY updated_at DESC) = 1
"""

Exact formatting is produced by SQLGlot and may change as SQLGlot changes.

After py-sql-cleaner extract jobs/load_users.py --out-dir sql:

Supported Input

The current MVP targets Python triple-quoted strings.

Supported:

query = """
SELECT *
FROM users
"""
load_users_sql = '''
SELECT *
FROM users
'''

Not targeted in the MVP:

query = "SELECT * FROM users"

Safety

py-sql-cleaner is conservative by default. It skips unsafe blocks instead of rewriting them.

Note

Skipped blocks are left unchanged. This is intentional: preserving runtime behavior is more important than formatting every SQL-looking string.

Always skipped by format and extract:

query = f"""
SELECT *
FROM users
WHERE user_id = {user_id}
"""
query = """
SELECT *
FROM users
WHERE ds = '{{ ds }}'
"""
query = """
SELECT *
FROM users
WHERE user_id = :user_id
"""
query = """
SELECT *
FROM users
WHERE user_id = %s
"""

f-strings, Jinja-like templates, and parameterized SQL are not complete SQL at rest. Python, a template engine, or a database driver fills those values at runtime, so rewriting or extracting the file contents directly could change runtime behavior.

py-sql-cleaner does not:

  • connect to databases
  • execute SQL
  • validate SQL against a database
  • inspect schemas
  • provide autocomplete
  • guarantee full database compatibility
  • fully support f-strings
  • fully support Jinja templates
  • rewrite parameterized SQL safely
  • format every possible SQL string

Commands

Command Purpose Example
list List embedded SQL blocks py-sql-cleaner list jobs/load_users.py
format Format embedded SQL in place py-sql-cleaner format jobs/load_users.py
check Check whether embedded SQL is formatted py-sql-cleaner check jobs/load_users.py
extract Extract embedded SQL into .sql files py-sql-cleaner extract jobs/load_users.py --out-dir sql
dialects List accepted dialect values py-sql-cleaner dialects

Use py-sql-cleaner --version to print the installed CLI version.

Documentation

Status

py-sql-cleaner is currently an early MVP.

The current focus is:

  • Python files
  • triple-quoted SQL strings
  • SQLGlot-backed SQL formatting, defaulting to generic SQL with --dialect support for explicitly enabled database-specific formatting
  • formatting
  • extracting SQL into .sql files

License

MIT