Repository Analysis

simonw/sqlite-utils

Python CLI utility and library for manipulating SQLite databases

16.7 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of simonw/sqlite-utils, a Python project with 2,161 GitHub stars. SynthScan v2.0 examined 28,919 lines of code across 84 source files, recording 595 pattern matches distributed across 11 syntactic categories. The overall adjusted score of 16.7 places this repository in the Moderate AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

16.7
Adjusted Score
16.7
Raw Score
100%
Time Factor
2026-08-14
Last Push
2.2K
Stars
Python
Language
28.9K
Lines of Code
84
Files
595
Pattern Hits
2026-08-29
Scan Date
0.04
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 0HIGH 3MEDIUM 7LOW 585

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 595 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Hyper-Verbose Identifiers521 hits · 400 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/db.py126def _column_definition_with_comments(STRING
LOWsqlite_utils/db.py359def _iter_complete_sql_statements(sql: str) -> Generator[str, None, None]:STRING
LOWsqlite_utils/db.py1230 def _ensure_no_open_transaction(self, operation: str) -> None:STRING
LOWsqlite_utils/db.py1387 def _resolve_foreign_key_casing(STRING
LOWsqlite_utils/db.py4305 def build_insert_queries_and_params(STRING
LOWsqlite_utils/create_table_parser.py832def check_references_identifier(expression: str, identifier: str) -> bool:CODE
LOWsqlite_utils/cli.py1061def insert_upsert_implementation(STRING
LOWsqlite_utils/cli.py2944 def yield_paths_and_relative_paths():STRING
LOWsqlite_utils/cli.py3469def _compatible_migration_set(obj):CODE
LOWsqlite_utils/cli.py3508def _stop_before_for_migration_set(stop_before, migration_set_name):CODE
LOWsqlite_utils/cli.py3779def _maybe_register_functions(db, functions_list):CODE
LOWsqlite_utils/utils.py87def maximize_csv_field_size_limit() -> None:CODE
LOWtests/test_conversions.py7def test_insert_all_conversion(fresh_db):CODE
LOWtests/test_conversions.py23def test_upsert_all_conversion(fresh_db):CODE
LOWtests/test_conversions.py38def test_table_constructor_conversion(fresh_db):CODE
LOWtests/test_default_value.py41def test_insert_empty_record_uses_default_values(fresh_db):CODE
LOWtests/test_enable_counts.py7def test_enable_counts_specific_table(fresh_db):CODE
LOWtests/test_enable_counts.py59def test_enable_counts_all_tables(fresh_db):CODE
LOWtests/test_enable_counts.py128def test_uses_counts_after_enable_counts(counts_db_path):CODE
LOWtests/test_utils.py58def test_maximize_csv_field_size_limit():CODE
LOWtests/test_transform.py124def test_transform_sql_table_with_primary_key(CODE
LOWtests/test_transform.py205def test_transform_sql_table_with_no_primary_key(CODE
LOWtests/test_transform.py232def test_transform_sql_with_no_primary_key_to_primary_key_of_id(fresh_db):CODE
LOWtests/test_transform.py257def test_transform_preserves_keyword_literal_defaults(fresh_db):CODE
LOWtests/test_transform.py301def test_transform_remove_a_not_null(fresh_db):CODE
LOWtests/test_transform.py312def test_transform_add_not_null_with_rename(fresh_db, not_null):CODE
LOWtests/test_transform.py332def test_transform_defaults_and_rename_column(fresh_db):CODE
LOWtests/test_transform.py365def test_transform_foreign_keys_persist(authors_db):CODE
LOWtests/test_transform.py380def test_transform_foreign_keys_survive_renamed_column(CODE
LOWtests/test_transform.py396def _add_country_city_continent(db):CODE
LOWtests/test_transform.py412def test_transform_drop_foreign_keys(fresh_db, use_pragma_foreign_keys):CODE
LOWtests/test_transform.py445def test_transform_verify_foreign_keys(fresh_db):CODE
LOWtests/test_transform.py464def test_transform_on_delete_cascade_does_not_delete_records(CODE
LOWtests/test_transform.py503def test_transform_in_transaction_refuses_destructive_on_delete(fresh_db, on_delete):STRING
LOWtests/test_transform.py535def test_transform_in_transaction_refuses_self_referential_cascade(fresh_db):STRING
LOWtests/test_transform.py558def test_transform_in_transaction_allowed_with_no_action_foreign_key(fresh_db):STRING
LOWtests/test_transform.py585def test_transform_in_transaction_allowed_for_child_table(fresh_db):STRING
LOWtests/test_transform.py608def test_transform_in_transaction_allowed_with_foreign_keys_off(fresh_db):STRING
LOWtests/test_transform.py630def test_transform_add_foreign_keys_from_scratch(fresh_db):STRING
LOWtests/test_transform.py676def test_transform_add_foreign_keys_from_partial(fresh_db, add_foreign_keys):STRING
LOWtests/test_transform.py716def test_transform_replace_foreign_keys(fresh_db, foreign_keys):STRING
LOWtests/test_transform.py737def test_transform_preserves_rowids(fresh_db, table_type):STRING
LOWtests/test_transform.py787def test_transform_to_strict_with_invalid_data(fresh_db):STRING
LOWtests/test_transform.py802def test_transform_strict_updates_default(fresh_db):STRING
LOWtests/test_transform.py816def test_transform_to_strict_not_supported(fresh_db, method_name):STRING
LOWtests/test_transform.py827def test_transform_preserves_any_column_in_strict_table(fresh_db):STRING
LOWtests/test_transform.py858def test_transform_any_column_from_strict_to_non_strict(fresh_db):STRING
LOWtests/test_transform.py918def test_transform_retains_indexes_with_foreign_keys(fresh_db):STRING
LOWtests/test_transform.py946def test_transform_with_indexes_errors(fresh_db):STRING
LOWtests/test_transform.py967def test_transform_rename_column_with_index(fresh_db, table_name, index_name):STRING
LOWtests/test_transform.py988def test_transform_recreates_renamed_index_from_metadata(fresh_db):STRING
LOWtests/test_transform.py1018def test_transform_rename_complex_index_errors(fresh_db, index_sql):STRING
LOWtests/test_transform.py1030def test_transform_with_unique_constraint_implicit_index(fresh_db):STRING
LOWtests/test_transform.py1049def test_transform_preserves_composite_unique_constraint(fresh_db):STRING
LOWtests/test_transform.py1076def test_transform_preserves_column_unique_collation(fresh_db):STRING
LOWtests/test_transform.py1093def test_transform_drops_entire_composite_unique_constraint(fresh_db):STRING
LOWtests/test_transform.py1110def test_transform_preserves_autoincrement_and_sequence(fresh_db):STRING
LOWtests/test_transform.py1138def test_transform_empty_string_to_null_for_numeric_types(STRING
LOWtests/test_transform.py1158def test_transform_preserves_view(fresh_db):STRING
LOWtests/test_transform.py1182def test_transform_variants_preserve_view(fresh_db, transform_params):STRING
461 more matches not shown…
Deep Nesting27 hits · 24 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/db.py508CODE
LOWsqlite_utils/db.py569CODE
LOWsqlite_utils/db.py1290CODE
LOWsqlite_utils/db.py1429CODE
LOWsqlite_utils/db.py1849CODE
LOWsqlite_utils/db.py2643CODE
LOWsqlite_utils/db.py2773CODE
LOWsqlite_utils/db.py3256CODE
LOWsqlite_utils/db.py3389CODE
LOWsqlite_utils/db.py4255CODE
LOWsqlite_utils/db.py4305CODE
LOWsqlite_utils/db.py4520CODE
LOWsqlite_utils/db.py4673CODE
LOWsqlite_utils/db.py5299CODE
LOWsqlite_utils/db.py2933CODE
LOWsqlite_utils/create_table_parser.py233CODE
LOWsqlite_utils/create_table_parser.py308CODE
LOWsqlite_utils/create_table_parser.py322CODE
LOWsqlite_utils/cli.py1061CODE
LOWsqlite_utils/cli.py2105CODE
LOWsqlite_utils/cli.py2263CODE
LOWsqlite_utils/cli.py2906CODE
LOWsqlite_utils/cli.py3742CODE
LOWsqlite_utils/cli.py2944CODE
LOWsqlite_utils/utils.py140CODE
LOWsqlite_utils/utils.py263CODE
LOWsqlite_utils/utils.py288CODE
Cross-Language Confusion3 hits · 12 pts
SeverityFileLineSnippetContext
HIGHsqlite_utils/db.py1082 # default into a string ('TRUE' instead of 1, 'NULL' instead of null).STRING
HIGHsqlite_utils/db.py5353 # Optimization - if all rows are null, don't run this querySTRING
HIGHtests/test_extracts.py71 # Null values should stay null, not be extracted into the lookup tableCOMMENT
Self-Referential Comments6 hits · 12 pts
SeverityFileLineSnippetContext
MEDIUMsqlite_utils/db.py546 # Create an in-memory database:COMMENT
MEDIUMsqlite_utils/db.py2201 # This method is defined on Queryable so it serves views too, whichSTRING
MEDIUMtests/test_transform.py1032 # Create a table with a UNIQUE constraint on 'name', which creates an implicit indexSTRING
MEDIUMtests/test_cli.py916 # Create a temporary file with function definitionsSTRING
MEDIUMtests/test_m2m.py164 # Create a candidateCOMMENT
MEDIUMdocs/conf.py6# This file is execfile()d with the current directory set to itsCOMMENT
AI Structural Patterns14 hits · 11 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/db.py569CODE
LOWsqlite_utils/db.py1429CODE
LOWsqlite_utils/db.py1700CODE
LOWsqlite_utils/db.py2285CODE
LOWsqlite_utils/db.py2540CODE
LOWsqlite_utils/db.py2643CODE
LOWsqlite_utils/db.py2773CODE
LOWsqlite_utils/db.py4018CODE
LOWsqlite_utils/db.py4604CODE
LOWsqlite_utils/db.py4673CODE
LOWsqlite_utils/db.py5031CODE
LOWsqlite_utils/db.py5069CODE
LOWsqlite_utils/db.py5117CODE
LOWsqlite_utils/cli.py1061CODE
Unused Imports11 hits · 11 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/__init__.py1CODE
LOWsqlite_utils/__init__.py2CODE
LOWsqlite_utils/__init__.py2CODE
LOWsqlite_utils/__init__.py3CODE
LOWsqlite_utils/__init__.py4CODE
LOWsqlite_utils/__init__.py4CODE
LOWsqlite_utils/recipes.py1CODE
LOWsqlite_utils/migrations.py7CODE
LOWsqlite_utils/migrations.py7CODE
LOWtests/test_register_function.py2CODE
LOWtests/test_register_function.py3CODE
Excessive Try-Catch Wrapping5 hits · 4 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/db.py968 except Exception:STRING
LOWsqlite_utils/cli.py1148 except Exception as e:STRING
LOWsqlite_utils/cli.py3320 except Exception as ex: # noqa: BLE001STRING
MEDIUMsqlite_utils/cli.py3317def wrapped_fn(value):CODE
LOWsqlite_utils/utils.py545 except Exception: # noqa: BLE001, S110CODE
Redundant / Tautological Comments3 hits · 3 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/db.py4784 # Check if this is list mode or dict modeSTRING
LOWsqlite_utils/cli.py3760 # Check if this is a file pathCOMMENT
LOWsqlite_utils/utils.py539 # Check if code is a direct callable referenceCOMMENT
Over-Commented Block3 hits · 3 pts
SeverityFileLineSnippetContext
LOWdocs/conf.py1import inspectCOMMENT
LOWdocs/conf.py181 #COMMENT
LOW.github/workflows/codeql-analysis.yml41 # If you wish to specify custom queries, you can do so here or in a config file.COMMENT
Modern Structural Boilerplate1 hit · 1 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/__init__.py6__all__ = [CODE
AI Slop Vocabulary1 hit · 0 pts
SeverityFileLineSnippetContext
LOWsqlite_utils/db.py5369 # No need to run the query if it will just return the results in reverse orderSTRING