class_docstr: The SQLStorageAdapter allows ChatterBot to store conversation
  data in any database supported by the SQL Alchemy ORM.
  
  All parameters are optional, by default a sqlite database is used.
  
  It will check if tables are present, if they are not, it will attempt
  to create the required tables.
  
  :keyword database_uri: eg: sqlite:///database_test.sqlite3',
      The database_uri can be specified to choose database driver.
  :type database_uri: str
class_docstr_tok: ["The","SQLStorageAdapter","allows","ChatterBot","to","store","conversation","data","in","any","database","supported","by","the","SQL","Alchemy","ORM",".","All","parameters","are","optional",",","by","default","a","sqlite","database","is","used",".","It","will","check","if","tables","are","present",",","if","they","are","not",",","it","will","attempt","to","create","the","required","tables",".",":","keyword","database_uri",":","eg",":","sqlite",":","\/\/\/database_test.sqlite3","'",",","The","database_uri","can","be","specified","to","choose","database","driver",".",":","type","database_uri",":","str"]
docstr: Returns a list of objects from the database.
  The kwargs parameter can contain any number
  of attributes. Only objects which contain all
  listed attributes and in which all values match
  for all listed attributes will be returned.
docstr_tok: ["Returns","a","list","of","objects","from","the","database",".","The","kwargs","parameter","can","contain","any","number","of","attributes",".","Only","objects","which","contain","all","listed","attributes","and","in","which","all","values","match","for","all","listed","attributes","will","be","returned","."]
code: def filter(self, **kwargs):
      """
      Returns a list of objects from the database.
      The kwargs parameter can contain any number
      of attributes. Only objects which contain all
      listed attributes and in which all values match
      for all listed attributes will be returned.
      """
      from sqlalchemy import or_
  
      Statement = self.get_model("statement")
      Tag = self.get_model("tag")
  
      session = self.Session()
  
      page_size = kwargs.pop("page_size", 1000)
      order_by = kwargs.pop("order_by", None)
      tags = kwargs.pop("tags", [])
      exclude_text = kwargs.pop("exclude_text", None)
      exclude_text_words = kwargs.pop("exclude_text_words", [])
      persona_not_startswith = kwargs.pop(
          "persona_not_startswith", None
      )
      search_text_contains = kwargs.pop("search_text_contains", None)
  
      # Convert a single sting into a list if only one tag is provided
      if type(tags) == str:
          tags = [tags]
  
      if len(kwargs) == 0:
          statements = session.query(Statement).filter()
      else:
          statements = session.query(Statement).filter_by(**kwargs)
  
      if tags:
          statements = statements.join(Statement.tags).filter(
              Tag.name.in_(tags)
          )
  
      if exclude_text:
          statements = statements.filter(
              ~Statement.text.in_(exclude_text)
          )
  
      if exclude_text_words:
          or_word_query = [
              Statement.text.ilike("%" + word + "%")
              for word in exclude_text_words
          ]
          statements = statements.filter(~or_(*or_word_query))
  
      if persona_not_startswith:
          statements = statements.filter(
              ~Statement.persona.startswith("bot:")
          )
  
      if search_text_contains:
          or_query = [
              Statement.search_text.contains(word)
              for word in search_text_contains.split(" ")
          ]
          statements = statements.filter(or_(*or_query))
  
      if order_by:
          if "created_at" in order_by:
              index = order_by.index("created_at")
              order_by[index] = Statement.created_at.asc()
  
          statements = statements.order_by(*order_by)
  
      total_statements = statements.count()
  
      for start_index in range(0, total_statements, page_size):
          for statement in statements.slice(
              start_index, start_index + page_size
          ):
              yield self.model_to_object(statement)
  
      session.close()
  
file_path: ChatterBot/chatterbot/storage/sql_storage.py
imports: from chatterbot.storage import StorageAdapter
label_desc: Use image node_id 7 for calling the SQLStorageAdapter obj's underlying member method code with example usage: obj.filter() without return types