Repository: truera/trulens
Issue: [BUG] TruLens Quickstart - OperationalError: (sqlite3.OperationalError) no such table: trulens_apps
Root cause: Configuration Error

**Bug Description**
When running through the TruLens quickstart notebook on Google Colab, with client and providers modified to use AzureOpenAI, I get an error running this code:

```
from trulens_eval import TruCustomApp
tru_rag = TruCustomApp(rag,
    app_id = 'RAG v1',
    feedbacks = [f_groundedness, f_answer_relevance, f_context_relevance])
```
The error returned is:
```
OperationalError: (sqlite3.OperationalError) no such table: trulens_apps
[SQL: SELECT trulens_apps.app_id AS trulens_apps_app_id, trulens_apps.app_json AS trulens_apps_app_json 
FROM trulens_apps 
WHERE trulens_apps.app_id = ?
 LIMIT ? OFFSET ?]
[parameters: ('RAG v1', 1, 0)]
(Background on this error at: https://sqlalche.me/e/20/e3q8)
```

**To Reproduce**
Run the above code while going through the [Quickstart notebook](https://colab.research.google.com/github/truera/trulens/blob/main/trulens_eval/examples/quickstart/quickstart.ipynb).

I don't know if this is only because of my changes to use AzureOpenAI (I don't have an OpenAI API key to test with).

The relevant things I changed to use Azure OpenAI are:
```
from openai import AzureOpenAI
oai_client = AzureOpenAI(
    api_key=api_key,
    api_version=api_version,
    azure_endpoint=azure_endpoint
)
...
...
provider = AzureOpenAI(
  azure_endpoint=azure_endpoint,
  api_key=api_key,
  api_version=api_version,
  deployment_name="..."
)
```

**Expected behavior**
No error

**Relevant Logs/Tracebacks**
OperationalError                          Traceback (most recent call last)
[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/base.py](https://localhost:8080/#) in _exec_single_context(self, dialect, context, statement, parameters)
   1970                 if not evt_handled:
-> 1971                     self.dialect.do_execute(
   1972                         cursor, str_statement, effective_parameters, context

18 frames
[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/default.py](https://localhost:8080/#) in do_execute(self, cursor, statement, parameters, context)
    918     def do_execute(self, cursor, statement, parameters, context=None):
--> 919         cursor.execute(statement, parameters)
    920 

OperationalError: no such table: trulens_apps

The above exception was the direct cause of the following exception:

OperationalError                          Traceback (most recent call last)
[<ipython-input-17-77c8e58a316b>](https://localhost:8080/#) in <cell line: 2>()
      1 from trulens_eval import TruCustomApp
----> 2 tru_rag = TruCustomApp(rag,
      3     app_id = 'RAG v1',
      4     feedbacks = [f_groundedness, f_answer_relevance, f_context_relevance])

[/usr/local/lib/python3.10/dist-packages/trulens_eval/tru_custom_app.py](https://localhost:8080/#) in __init__(self, app, methods_to_instrument, **kwargs)
    392 
    393         # This does instrumentation:
--> 394         super().__init__(**kwargs)
    395 
    396         # Needed to split this part to after the instrumentation so that the

[/usr/local/lib/python3.10/dist-packages/trulens_eval/app.py](https://localhost:8080/#) in __init__(self, tru, feedbacks, **kwargs)
    566             self._start_manage_pending_feedback_results()
    567 
--> 568         self._tru_post_init()
    569 
    570     def __del__(self):

[/usr/local/lib/python3.10/dist-packages/trulens_eval/app.py](https://localhost:8080/#) in _tru_post_init(self)
    682             self.db = self.tru.db
    683 
--> 684             self.db.insert_app(app=self)
    685 
    686             if self.feedback_mode != FeedbackMode.NONE:

[/usr/local/lib/python3.10/dist-packages/trulens_eval/database/sqlalchemy.py](https://localhost:8080/#) in insert_app(self, app)
    337         with self.session.begin() as session:
    338             if _app := session.query(self.orm.AppDefinition
--> 339                                     ).filter_by(app_id=app.app_id).first():
    340 
    341                 _app.app_json = app.model_dump_json()

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/query.py](https://localhost:8080/#) in first(self)
   2726             return self._iter().first()  # type: ignore
   2727         else:
-> 2728             return self.limit(1)._iter().first()  # type: ignore
   2729 
   2730     def one_or_none(self) -> Optional[_T]:

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/query.py](https://localhost:8080/#) in _iter(self)
   2825 
   2826         statement = self._statement_20()
-> 2827         result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
   2828             statement,
   2829             params,

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py](https://localhost:8080/#) in execute(self, statement, params, execution_options, bind_arguments, _parent_execute_state, _add_event)
   2304 
   2305         """
-> 2306         return self._execute_internal(
   2307             statement,
   2308             params,

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py](https://localhost:8080/#) in _execute_internal(self, statement, params, execution_options, bind_arguments, _parent_execute_state, _add_event, _scalar_result)
   2189 
   2190         if compile_state_cls:
-> 2191             result: Result[Any] = compile_state_cls.orm_execute_statement(
   2192                 self,
   2193                 statement,

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/context.py](https://localhost:8080/#) in orm_execute_statement(cls, session, statement, params, execution_options, bind_arguments, conn)
    291         conn,
    292     ) -> Result:
--> 293         result = conn.execute(
    294             statement, params or {}, execution_options=execution_options
    295         )

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/base.py](https://localhost:8080/#) in execute(self, statement, parameters, execution_options)
   1420             raise exc.ObjectNotExecutableError(statement) from err
   1421         else:
-> 1422             return meth(
   1423                 self,
   1424                 distilled_parameters,

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/sql/elements.py](https://localhost:8080/#) in _execute_on_connection(self, connection, distilled_params, execution_options)
    512             if TYPE_CHECKING:
    513                 assert isinstance(self, Executable)
--> 514             return connection._execute_clauseelement(
    515                 self, distilled_params, execution_options
    516             )

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/base.py](https://localhost:8080/#) in _execute_clauseelement(self, elem, distilled_parameters, execution_options)
   1642             linting=self.dialect.compiler_linting | compiler.WARN_LINTING,
   1643         )
-> 1644         ret = self._execute_context(
   1645             dialect,
   1646             dialect.execution_ctx_cls._init_compiled,

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/base.py](https://localhost:8080/#) in _execute_context(self, dialect, constructor, statement, parameters, execution_options, *args, **kw)
   1848             return self._exec_insertmany_context(dialect, context)
   1849         else:
-> 1850             return self._exec_single_context(
   1851                 dialect, context, statement, parameters
   1852             )

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/base.py](https://localhost:8080/#) in _exec_single_context(self, dialect, context, statement, parameters)
   1988 
   1989         except BaseException as e:
-> 1990             self._handle_dbapi_exception(
   1991                 e, str_statement, effective_parameters, cursor, context
   1992             )

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/base.py](https://localhost:8080/#) in _handle_dbapi_exception(self, e, statement, parameters, cursor, context, is_sub_exec)
   2355             elif should_wrap:
   2356                 assert sqlalchemy_exception is not None
-> 2357                 raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
   2358             else:
   2359                 assert exc_info[1] is not None

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/base.py](https://localhost:8080/#) in _exec_single_context(self, dialect, context, statement, parameters)
   1969                             break
   1970                 if not evt_handled:
-> 1971                     self.dialect.do_execute(
   1972                         cursor, str_statement, effective_parameters, context
   1973                     )

[/usr/local/lib/python3.10/dist-packages/sqlalchemy/engine/default.py](https://localhost:8080/#) in do_execute(self, cursor, statement, parameters, context)
    917 
    918     def do_execute(self, cursor, statement, parameters, context=None):
--> 919         cursor.execute(statement, parameters)
    920 
    921     def do_execute_no_params(self, cursor, statement, context=None):

OperationalError: (sqlite3.OperationalError) no such table: trulens_apps
[SQL: SELECT trulens_apps.app_id AS trulens_apps_app_id, trulens_apps.app_json AS trulens_apps_app_json 
FROM trulens_apps 
WHERE trulens_apps.app_id = ?
 LIMIT ? OFFSET ?]
[parameters: ('RAG v1', 1, 0)]
(Background on this error at: https://sqlalche.me/e/20/e3q8)

**Environment:**
 - OS: Google Colab
 - Python Version: Python 3
 - TruLens version trulens_eval-0.28.0-py3-none-any.whl
 - Versions of other relevant installed libraries
   - chromadb-0.4.24-py3-none-any.whl
   - openai-1.23.1-py3-none-any.whl

**Additional context**


<!-- Answer -->
The error you're encountering, `OperationalError: no such table: trulens_apps`, suggests that the database migrations necessary for creating the `trulens_apps` table haven't been applied. This is a common issue when the database setup steps are missed or incomplete. To resolve this, you'll need to ensure that all database migrations are correctly applied. Here's a more streamlined approach to tackle this problem:

1. **Check Migration Scripts**: Ensure that any migration scripts provided by TruLens are accessible and correctly set up in your project. These scripts are responsible for setting up the database schema, including the creation of the `trulens_apps` table.

2. **Apply Migrations**: Use a database migration tool, such as Alembic, to apply migrations. If you're working within a Python script or a Jupyter notebook, you can programmatically apply migrations using Alembic's command functions. Here's a simplified example:

   ```python
   from alembic.config import Config
   from alembic import command

   alembic_cfg = Config("/path/to/your/alembic.ini")
   command.upgrade(alembic_cfg, "head")
   ```

   Replace `"/path/to/your/alembic.ini"` with the path to your Alembic configuration file. This step will create the necessary database tables, including `trulens_apps`.

3. **Verify Database Connection**: If you're running this in an environment like Google Colab, ensure that your notebook has the correct database connection settings and that it can communicate with the database where the migrations need to be applied.

By following these steps, you should be able to resolve the `OperationalError` by ensuring the `trulens_apps` table is created in your database. If you continue to face issues or have any more questions, feel free to ask.

## Sources
- [trulens_eval/trulens_eval/database/migrations/versions/1_first_revision.py](https://github.com/truera/trulens/blob/main/trulens_eval/trulens_eval/database/migrations/versions/1_first_revision.py)
- [trulens_eval/trulens_eval/database/legacy/migration.py](https://github.com/truera/trulens/blob/main/trulens_eval/trulens_eval/database/legacy/migration.py)

<!-- Dosu Comment Footer -->
<details>
<summary>

#### About Dosu
</summary>

This response is meant to be useful and save you time. It is **not meant to be a precise solution**, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.
</details>


I must be missing something, but given the quickstart doesn't mention anything related to database setup, I'm not sure how I should best proceed.

I came across this issue as well. Have you been able to find a solution for it yet?

Yeah, I've found a solution. You need to downgrade Trulens to version 0.27.0.

Hi all; I made a patch release 0.28.1 which addresses something which might be the cause of op's problem as well. Can you take a look by upgrading `trulens_eval`?

Thanks @34RTHY and @piotrm0 . Both of those things worked for me and allowed me to continue in the quickstart.