Docs for TrueQuery 0.1.6View as Markdown
pandas
A .py file that imports pandas is read with Python's own parser; pandas
is never imported and your code never runs. The checks look for pandas
code that runs without an error and gives the wrong data:
- a write through a chain (
df[mask]["col"] = v,df["col"].fillna(0, inplace=True)), which never reaches the DataFrame under pandas 3 (checked on every edit); - a write to the row of an
iterrows()loop, which changes a copy; groupby(...).first()/.last(), which can build a row from values of different input rows;sort_valueson one column (an unstable sort) deciding which rowdrop_duplicateskeeps;to_sql(if_exists="replace"), which drops the table's keys, constraints and column types;- off by default (they fire on most code and depend on data the checker
can't see):
merge/joinwith novalidate=, andgroupbywith nodropna=.
A DataFrame is a name the file builds from pandas (pd.read_*,
pd.DataFrame(...), pd.concat, pd.merge, a method of another known
DataFrame) or annotates as pd.DataFrame. A name the checker can't follow
(a parameter with no annotation, a value from another module) isn't
reported on. The receipt counts these files as pandas in N Python files.
Checks that need to know what a column means (money, units, time zones)
come with contracts.
An example#
A small example file, written for these docs:
import pandas as pd
orders = pd.read_csv("orders.csv")
# Set VAT on EU orders.
orders[orders.region == "EU"]["vat"] = 0.2
# Latest order per customer.
latest = orders.sort_values("ordered_at").drop_duplicates("customer_id", keep="last")
# First value of each column, per customer.
summary = orders.groupby("customer_id").first()
summary.to_sql("customer_summary", engine, if_exists="replace")A real run on it:
$ truequery review etl/clean_orders.py
etl/clean_orders.py:6:1 [error] py/pandas-no-chained-assignment — chained assignment: the write lands on a temporary copy, so the DataFrame never changes
fix: assign in one step on the DataFrame itself: df.loc[rows, "col"] = value
etl/clean_orders.py:9:43 [warning] py/pandas-dedupe-unstable-sort — drop_duplicates keeps a row picked by sort_values on line 9: one key, default (unstable) sort, so rows that tie on the key come out in any order
fix: sort by the key plus a unique tiebreaker column, or pass kind="stable" if the input order is the intended tiebreaker
etl/clean_orders.py:12:41 [warning] py/pandas-groupby-first-mixes-rows — groupby(...).first() takes the first non-null value of each column separately, so one output row can mix values from different input rows
fix: to keep whole rows: sort, then .nth(0) / .nth(-1) (or drop_duplicates(subset=keys)); or pass skipna=False
etl/clean_orders.py:14:9 [warning] py/pandas-to-sql-replace — to_sql(if_exists="replace") drops the table and creates a new one with types pandas guesses: its keys, constraints, indexes, column types and grants are lost without an error
fix: empty the table (DELETE or TRUNCATE) and write with if_exists="append", so the table's definition stays
TrueQuery receipt
Checked 0 SQL files · pandas in 1 Python file
Found 1 error · 3 warnings
Not checked your data: TrueQuery reads files and never connects to your database
Not checked pandas: only DataFrames a file builds or annotates itself are followed; what a column means (money, units, time zones) needs contractsSee every check, on or off, in all 32 checks.