conds = []
        if ids:
            conds.extend([f"{self.config.column_map['id']} = '{id}'" for id in ids])
        if where_str:
            conds.append(where_str)
        assert len(conds) > 0
        where_str_final = " AND ".join(conds)
        qstr = (
            f"DELETE FROM {self.config.database}.{self.config.table} "
            f"WHERE {where_str_final}"
        )
        try:
            self.client.command(qstr)
            return True
        except Exception as e:
            logger.error(str(e))
            return False
    @property
    def metadata_column(self) -> str:
        return self.config.column_map["metadata"]
[docs]class MyScaleWithoutJSON(MyScale):
    """MyScale vector store without metadata column
    This is super handy if you are working to a SQL-native table
    """
[docs]    def __init__(
        self,
        embedding: Embeddings,
        config: Optional[MyScaleSettings] = None,
        must_have_cols: List[str] = [],
        **kwargs: Any,
    ) -> None:
        """Building a myscale vector store without metadata column
        embedding (Embeddings): embedding model
        config (MyScaleSettings): Configuration to MyScale Client
        must_have_cols (List[str]): column names to be included in query
        Other keyword arguments will pass into
            [clickhouse-connect](https://docs.myscale.com/)
        """
        super().__init__(embedding, config, **kwargs)
        self.must_have_cols: List[str] = must_have_cols
    def _build_qstr(
        self, q_emb: List[float], topk: int, where_str: Optional[str] = None