class_docstr: Knowledge base controller handles all
  manages knowledge bases
class_docstr_tok: ["Knowledge","base","controller","handles","all","manages","knowledge","bases"]
docstr: Add a new knowledge base to the database
docstr_tok: ["Add","a","new","knowledge","base","to","the","database"]
code: def add(
      self,
      name: str,
      project_name: str,
      embedding_model: Identifier,
      storage: Identifier,
      params: dict,
      if_not_exists: bool = False,
  ) -> db.KnowledgeBase:
      """
      Add a new knowledge base to the database
      """
      # check if knowledge base already exists
  
      # get project id
  
      project = self.session.database_controller.get_project(
          project_name
      )
  
      project_id = project.id
  
      # not difference between cases in sql
      name = name.lower()
  
      kb = self.get(name, project_id)
      if kb is not None:
          if if_not_exists:
              return kb
          raise EntityExistsError("Knowledge base already exists", name)
  
      if embedding_model is None:
          # create default embedding model
          model_name = self._create_default_embedding_model(
              project.name, name
          )
  
      else:
          # get embedding model from input
          model_name = embedding_model.parts[-1]
  
      if embedding_model is not None and len(embedding_model.parts) > 1:
          # model project is set
          model_project = self.session.database_controller.get_project(
              embedding_model.parts[-2]
          )
      else:
          model_project = project
  
      model = self.session.model_controller.get_model(
          name=model_name, project_name=model_project.name
      )
      model_record = db.Predictor.query.get(model["id"])
      embedding_model_id = model_record.id
  
      # search for the vector database table
      if storage is None:
          # create chroma db with same name
          vector_table_name = "default_collection"
          vector_db_name = self._create_persistent_chroma(name)
      elif len(storage.parts) != 2:
          raise ValueError(
              "Storage param has to be vector db with table"
          )
      else:
          vector_db_name, vector_table_name = storage.parts
  
      vector_database_id = self.session.integration_controller.get(
          vector_db_name
      )["id"]
  
      # create table in vectordb
      self.session.datahub.get(
          vector_db_name
      ).integration_handler.create_table(vector_table_name)
  
      kb = db.KnowledgeBase(
          name=name,
          project_id=project_id,
          vector_database_id=vector_database_id,
          vector_database_table=vector_table_name,
          embedding_model_id=embedding_model_id,
          params=params,
      )
      db.session.add(kb)
      db.session.commit()
      return kb
  
imports: import copy
  from typing import List
  import pandas
  import mindsdb_sql.planner.utils
  from mindsdb_sql.parser.ast import BinaryOperation, Constant, Identifier, Select, Update, Delete, Star
  from mindsdb_sql.parser.dialects.mindsdb import CreatePredictor
  import mindsdb.interfaces.storage.db
  from mindsdb.integrations.libs.vectordatabase_handler import TableField
  from mindsdb.utilities.exception import EntityExistsError, EntityNotExistsError
label_desc: Use image node_id 2 for calling the KnowledgeBaseController obj's underlying member method code with example usage: obj.add(name, project_name, embedding_model, storage, params, if_not_exists) and returns: kb, kb