Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make integer primary key compatible with oracle #5197

Merged
merged 12 commits into from
Feb 13, 2020
4 changes: 4 additions & 0 deletions changelog/5197.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fixed incompatibility with Oracle, integer primary key is now a sequence and so can
akelad marked this conversation as resolved.
Show resolved Hide resolved
be used with Oracle.

Added docs for setting up Oracle.
akelad marked this conversation as resolved.
Show resolved Hide resolved
57 changes: 57 additions & 0 deletions docs/api/tracker-stores.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,63 @@ SQLTrackerStore
- ``login_db`` (default: ``None``): Alternative database name to which initially connect, and create the database specified by `db` (PostgreSQL only)
- ``query`` (default: ``None``): Dictionary of options to be passed to the dialect and/or the DBAPI upon connect


:Supported Databases:
akelad marked this conversation as resolved.
Show resolved Hide resolved
- PostgreSQL
- Oracle > 11.0
- SQLite


:Oracle Configuration:


To use the SQLTrackerStore with Oracle, there are a few additional steps.
First, create a database ``tracker`` in your Oracle database and create a user with access to it.
Create a sequence in the database with the following command (where username is the user you created):
akelad marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: sql

CREATE SEQUENCE username.events_seq;

Next you have to extend the Rasa Open Source image to include the necessary drivers and clients.

First download the Oracle Instant Client from `here <https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html>`_,
rename it to ``oracle.rpm`` and store it in the directory from where you'll be building the docker image.

Copy this into a file called ``Dockerfile``:

.. code-block:: bash

FROM rasa/rasa:|version|-full
# Switch to root user to install packages
USER root
RUN apt-get update -qq \
&& apt-get install -y --no-install-recommends \
alien \
libaio1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Copy in oracle instaclient
# https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html
COPY oracle.rpm oracle.rpm
# Install the Python wrapper library for the Oracle drivers
RUN pip install cx-Oracle
akelad marked this conversation as resolved.
Show resolved Hide resolved
# Install Oracle client libraries
RUN alien -i oracle.rpm
USER 1001

Then build the docker image:

.. code-block:: bash

docker build . -t rasa-oracle:latest
akelad marked this conversation as resolved.
Show resolved Hide resolved

Now you can configure the tracker store in the ``endpoints.yml`` as described above,
and start the container. Read more about :ref:`running-rasa-with-docker`.


akelad marked this conversation as resolved.
Show resolved Hide resolved


RedisTrackerStore
~~~~~~~~~~~~~~~~~~

Expand Down
3 changes: 2 additions & 1 deletion rasa/core/tracker_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,11 @@ class SQLEvent(Base):
"""Represents an event in the SQL Tracker Store"""

from sqlalchemy import Column, Integer, String, Float, Text
from rasa.core.utils import create_sequence

__tablename__ = "events"

id = Column(Integer, primary_key=True)
id = Column(Integer, create_sequence(__tablename__), primary_key=True)
sender_id = Column(String(255), nullable=False, index=True)
type_name = Column(String(255), nullable=False)
timestamp = Column(Float)
Expand Down
11 changes: 11 additions & 0 deletions rasa/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from rasa.utils.endpoints import EndpointConfig, read_endpoint_config
from sanic import Sanic
from sanic.views import CompositionView
from sqlalchemy import Sequence

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -538,3 +539,13 @@ def _log_and_get_default_number_of_workers():
f"no `RedisLockStore` endpoint configuration has been found."
)
return _log_and_get_default_number_of_workers()


def create_sequence(table_name: Text) -> Sequence:
akelad marked this conversation as resolved.
Show resolved Hide resolved
"""Creates a sequence object"""
akelad marked this conversation as resolved.
Show resolved Hide resolved

from sqlalchemy.ext.declarative import declarative_base

sequence_name = f"{table_name}_seq"
Base = declarative_base()
return Sequence(sequence_name, metadata=Base.metadata, optional=True)