Storage Adapters

Storage adapters provide an interface that allows ChatterBot to connect to different storage technologies. Each adapter is optimized for different use cases:

  • Redis Vector Storage: Semantic similarity search using vector embeddings (best for contextual AI responses)

  • SQL Storage: Traditional pattern matching with POS-lemma indexing (best for exact phrase matching)

  • MongoDB Storage: NoSQL document storage with flexible schema

  • Django Storage: Integrated with Django ORM for web applications

The storage adapter that your bot uses can be specified by setting the storage_adapter parameter to the import path of the storage adapter you want to use.

chatbot = ChatBot(
    "My ChatterBot",
    storage_adapter="chatterbot.storage.SQLStorageAdapter"
)

Built-in Storage Adapters

ChatterBot includes multiple storage adapters for different AI and database technologies:

Choosing a Storage Adapter

For Semantic AI Chatbots (Recommended for modern conversational AI):

Note that as of December 2025, the Redis Vector Storage Adapter is still an experimental beta feature.

Use Redis Vector Storage when you need:

  • Context-aware responses based on meaning, not keywords

  • Vector embeddings for semantic similarity search

  • Automatic confidence scoring from cosine similarity

  • Best match for conversational AI and natural language understanding

For Pattern-Based Matching:

Use SQL Storage when you need:

  • Exact phrase or pattern matching

  • POS-lemma bigram indexing

  • Traditional database features (ACID compliance)

  • Lower memory footprint

For Flexibility:

Use MongoDB or Django Storage for schema flexibility and web framework integration.

Common storage adapter attributes

Each storage adapter inherits the following attributes and methods.

class chatterbot.storage.StorageAdapter(*args, **kwargs)[source]

This is an abstract class that represents the interface that all storage adapters should implement.

exception AdapterMethodNotImplementedError[source]

An exception to be raised when a storage adapter method has not been implemented. Typically this indicates that the method should be implement in a subclass.

exception EmptyDatabaseException(message=None)[source]
close()[source]

Close any open connections or sessions. This method should be called when the storage adapter is no longer needed to properly clean up resources and avoid resource warnings.

count() int[source]

Return the number of entries in the database.

create(**kwargs)[source]

Creates a new statement matching the keyword arguments specified. Returns the created statement.

create_many(statements)[source]

Creates multiple statement entries.

drop()[source]

Drop the database attached to a given adapter.

filter(**kwargs)[source]

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.

Parameters:
  • page_size – The maximum number of records to load into memory at once when returning results. Defaults to 1000

  • order_by – The field name that should be used to determine the order that results are returned in. Defaults to None

  • tags – A list of tags. When specified, the results will only include statements that have a tag in the provided list. Defaults to [] (empty list)

  • exclude_text – If the text of a statement is an exact match for the value of this parameter the statement will not be included in the result set. Defaults to None

  • exclude_text_words – If the text of a statement contains a word from this list then the statement will not be included in the result set. Defaults to [] (empty list)

  • persona_not_startswith – If the persona field of a statement starts with the value specified by this parameter, then the statement will not be returned in the result set. Defaults to None

  • search_text_contains – If the search_text field of a statement contains a word that is in the string provided to this parameter, then the statement will be included in the result set. Defaults to None

  • search_in_response_to – If the search_in_response_to field of a statement contains a word that is in the string provided to this parameter, then the statement will be included in the result set. Defaults to None

get_model(model_name)[source]

Return the model class for a given model name.

model_name is case insensitive.

get_object(object_name)[source]

Return the class for a given object name.

object_name is case insensitive.

get_preferred_search_algorithm()[source]

Returns the search algorithm name preferred by this storage adapter. Returns None by default, meaning the default search algorithm will be used.

Storage adapters should override this method to specify their preferred search algorithm based on their capabilities.

Available Search Algorithms:

  • ‘indexed_text_search’ (default): Uses POS-lemma indexed fields (search_text, search_in_response_to). Python-based Levenshtein distance comparison. Requires PosLemmaTagger. Best for: Exact pattern matching.

  • ‘semantic_vector_search’: Uses raw text with vector similarity. Delegates to storage.filter(search_in_response_to_contains=text). No tagger required (works with NoOpTagger). Confidence from storage adapter (cosine similarity). Best for: Context-aware AI responses, semantic understanding.

  • ‘text_search’ (fallback): Compares raw text without indexes. Slower but works with any storage. Uses comparison functions on all statements.

Example - Vector Storage:

def get_preferred_search_algorithm(self):
    return 'semantic_vector_search'

Example - SQL Storage:

def get_preferred_search_algorithm(self):
    return None  # Use default 'indexed_text_search'
Returns:

Search algorithm name string or None

get_preferred_tagger()[source]

Returns the tagger class preferred by this storage adapter. Returns None by default, meaning the default tagger will be used.

Storage adapters should override this method to specify their preferred tagger based on their search capabilities.

Available Taggers:

  • NoOpTagger: Returns text unchanged (for vector-based storage). No spaCy model loading (~500MB memory saved). Faster startup (<1 second vs 2-5 seconds). Use when storage handles semantic search natively.

  • PosLemmaTagger: Creates POS-lemma bigrams (default, for SQL). Enables pattern matching (e.g., “NOUN:cat VERB:run”). Requires spaCy language model. Best for exact phrase matching.

  • LowercaseTagger: Simple lowercase transformation. Minimal processing overhead. Case-insensitive matching.

Example - Vector Storage:

def get_preferred_tagger(self):
    from chatterbot.tagging import NoOpTagger
    return NoOpTagger

Example - Traditional Storage:

def get_preferred_tagger(self):
    return None  # Use default PosLemmaTagger
Returns:

Tagger class or None

get_random()[source]

Returns a random statement from the database.

remove(statement_text)[source]

Removes the statement that matches the input text. Removes any responses from statements where the response text matches the input text.

update(statement)[source]

Modifies an entry in the database. Creates an entry if one does not exist.

Database Migrations

Various frameworks such as Django and SQL Alchemy support functionality that allows revisions to be made to databases programmatically. This makes it possible for updates and revisions to structures in the database to be be applied in consecutive version releases.

The following explains the included migration process for each of the databases that ChatterBot comes with support for.

  • Django: Full schema migrations and data migrations will be included with each release.

  • SQL Alchemy: No migrations are currently provided in releases. If you require migrations between versions Alembic is the recommended solution for generating them.

  • MongoDB: No migrations are provided.

  • Redis: No migrations are provided.

Further Reading