ValueError: You are trying to merge on object and int64 columns (pandas)
Your join keys have different dtypes — one side holds strings, the other integers. Cast both key columns to the same type before merging; string is usually the safe choice.
Updated
The error
ValueError: You are trying to merge on object and int64 columns for key 'customer_id'. If you wish to proceed you should use pd.concat
What it means
pd.merge joins two tables on a key column. On one side the key is dtype object (which in pandas almost always means strings), on the other it is int64. The string "1042" and the integer 1042 never match, so pandas stops rather than produce an empty join.
Ignore the hint about pd.concat. Concatenation stacks tables; it is not a join and will not do what you want here.
Why it happens
The same ID column gets read differently from different files. A CSV column containing 001042 loads as text, preserving the leading zeros. The same IDs exported from a database load as integers. A single stray value like "unknown" in an otherwise numeric column also forces the whole column to object.
Excel exports are a repeat offender: a column formatted as text comes through as strings even when every value looks numeric.
How to fix it
1. Look at both dtypes first.
print(orders["customer_id"].dtype, customers["customer_id"].dtype)object int64
2. Cast both sides to string — the safe default. Strings survive leading zeros and mixed values.
orders["customer_id"] = orders["customer_id"].astype(str).str.strip()
customers["customer_id"] = customers["customer_id"].astype(str).str.strip()
result = orders.merge(customers, on="customer_id", how="left")The .str.strip() matters: "1042 " with a trailing space will not match "1042".
3. Or cast both sides to integer, when the IDs are truly numeric.
orders["customer_id"] = pd.to_numeric(orders["customer_id"], errors="coerce")
bad = orders[orders["customer_id"].isna()]
print(len(bad), "rows had non-numeric IDs")Inspect the bad rows before continuing — they are the values that forced the column to object in the first place.
4. Watch for NaN turning integers into floats. A key column with missing values becomes float64, and 1042.0 versus 1042 causes subtler trouble. Use the nullable integer dtype:
orders["customer_id"] = orders["customer_id"].astype("Int64") # capital IHow to prevent it
Fix dtypes at load time, not at merge time: pd.read_csv("orders.csv", dtype={"customer_id": str}). Check the merge result immediately — a left join that produced mostly NaN on the right side means keys did not match, even when no error was raised.