pandas-dev/pandas · error · TypeError
passing a filterable condition to a non-table indexer [{self
Error message
passing a filterable condition to a non-table indexer [{self}] What it means
Raised by FilterBinOp.evaluate in pandas.core.computation.pytables when the operator is not '==' or '!=' (i.e. an inequality like <, >, <=, >=, in, not in) AND self.is_in_table is False. is_in_table checks that queryables has a non-None entry for the column. The error is a TypeError and signals that you are trying an inequality filter on a column that is not stored as a data_column (only equality/list membership can sometimes be optimized via the index).
Source
Thrown at pandas/core/computation/pytables.py:347
self.filter[2],
)
return self
def format(self):
"""return the actual filter format"""
return [self.filter]
# error: Signature of "evaluate" incompatible with supertype "BinOp"
def evaluate(self) -> Self | None: # type: ignore[override]
if not self.is_valid:
raise ValueError(f"query term is not valid [{self}]")
rhs = self.conform(self.rhs)
values = list(rhs)
if self.op not in ["==", "!="]:
if not self.is_in_table:
raise TypeError(
f"passing a filterable condition to a non-table indexer [{self}]"
)
return None
if self.is_in_table and len(values) <= self._max_selectors:
return None
filter_op = self.generate_filter_op()
self.filter = (self.lhs.value, filter_op, Index(values))
return self
def generate_filter_op(self, invert: bool = False):
if (self.op == "!=" and not invert) or (self.op == "==" and invert):
return lambda axis, vals: ~axis.isin(vals)
else:
return lambda axis, vals: axis.isin(vals)
class JointFilterBinOp(FilterBinOp):View on GitHub (pinned to 71959b8cb9)
Solutions
- Declare the column as a data_column when writing: store.put('df', df, format='table', data_columns=['price']).
- Use equality/list membership if you cannot rewrite: where='price == 100' may still work for indexed columns, but inequalities require data_columns.
- Filter in pandas after reading: df = store.get('df'); df[df['price'] > 100].
- For range queries on the index, use the index column name directly (e.g. where='index > 100').
Example fix
# before
store.select('df', where='price > 100') # TypeError: passing a filterable condition to a non-table indexer
# after
df.to_hdf(path, 'df', format='table', data_columns=['price'])
store.select('df', where='price > 100')
# or:
df = pd.read_hdf(path, 'df')
df[df['price'] > 100] Defensive patterns
Strategy: validation
Validate before calling
def supports_inequality(store, key, column) -> bool:
storer = store.get_storer(key)
data_cols = list(storer.data_columns or [])
idx_cols = [getattr(a, 'name', None) for a in (storer.index_axes or [])]
return column in data_cols or column in idx_cols
# before store.select('df', where=f'{col} > 5'):
if not supports_inequality(store, 'df', col):
raise TypeError(f'{col!r} must be a data_column for inequality queries') Type guard
def is_data_column(store, key, column) -> bool:
try:
return column in (store.get_storer(key).data_columns or [])
except Exception:
return False
Try / catch
try:
store.select('df', where=f'{col} > 5')
except TypeError as e:
if 'filterable condition' in str(e):
df = store.get('df')
result = df[df[col] > 5]
else:
raise Prevention
- Declare range-query columns as data_columns when writing.
- Use the index column for inequalities when possible.
- Read+filter in pandas for non-indexed columns.
When it happens
Trigger: store.select('df', where='price > 100') where 'price' is not a data_column; store.select('df', where='date < 20200101') against a non-indexed date column.
Common situations: Default table writes only make the index queryable for inequalities; users assume all columns support range queries; using inequality on a string/categorical column without data_columns=True.
Related errors
- name {self.name!r} is not defined
- arithmetic operations are not supported inside an HDFStore '
- Cannot compare {conv_val} of type {type(conv_val)} to {kind}
- query term is not valid [{self}]
- unable to collapse Joint Filters
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/88ed7c6e4a303932.
Report an issue: GitHub.