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

add db schema #1839

Merged
merged 9 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion alerta/database/backends/mongodb/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

class Backend(Database):

def create_engine(self, app, uri, dbname=None, raise_on_error=True):
def create_engine(self, app, uri, dbname=None, schema=None, raise_on_error=True):
self.uri = uri
self.dbname = dbname

Expand Down
12 changes: 9 additions & 3 deletions alerta/database/backends/postgres/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import psycopg2
from flask import current_app
from psycopg2.extensions import AsIs, adapt, register_adapter
from psycopg2.extras import Json, NamedTupleCursor, register_composite
from psycopg2.extras import Json, NamedTupleCursor, register_composite, CompositeCaster

from alerta.app import alarm_model
from alerta.database.base import Database
Expand Down Expand Up @@ -62,26 +62,29 @@ def __str__(self):

class Backend(Database):

def create_engine(self, app, uri, dbname=None, raise_on_error=True):
def create_engine(self, app, uri, dbname=None, schema='public', raise_on_error=True):
self.uri = uri
self.dbname = dbname
self.schema = schema

lock = threading.Lock()
with lock:
conn = self.connect()

with app.open_resource('sql/schema.sql') as f:
try:
conn.cursor().execute(f.read())
conn.commit()
except Exception as e:
print("\n\n\n\nErreur\n\n\n\n")
satterly marked this conversation as resolved.
Show resolved Hide resolved
if raise_on_error:
raise
app.logger.warning(e)

register_adapter(dict, Json)
register_adapter(datetime, self._adapt_datetime)
register_composite(
'history',
schema + '.history' if schema else 'history',
conn,
globally=True
)
Expand All @@ -97,6 +100,7 @@ def connect(self):
dbname=self.dbname,
cursor_factory=NamedTupleCursor
)

conn.set_client_encoding('UTF8')
break
except Exception as e:
Expand All @@ -111,6 +115,8 @@ def connect(self):
time.sleep(backoff)

if conn:
conn.cursor().execute("SET search_path TO {}".format(self.schema))
conn.commit()
return conn
else:
raise RuntimeError(f'Database connect error. Failed to connect after {MAX_RETRIES} retries.')
Expand Down
4 changes: 2 additions & 2 deletions alerta/database/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def init_db(self, app):
self.__class__ = type('DatabaseImpl', (cls.Backend, Database), {})

try:
self.create_engine(app, uri=app.config['DATABASE_URL'], dbname=app.config['DATABASE_NAME'],
self.create_engine(app, uri=app.config['DATABASE_URL'], dbname=app.config['DATABASE_NAME'], schema=app.config['DATABASE_SCHEMA'],
raise_on_error=app.config['DATABASE_RAISE_ON_ERROR'])
except Exception as e:
if app.config['DATABASE_RAISE_ON_ERROR']:
Expand All @@ -65,7 +65,7 @@ def init_db(self, app):

app.teardown_appcontext(self.teardown_db)

def create_engine(self, app, uri, dbname=None, raise_on_error=True):
def create_engine(self, app, uri, dbname=None, schema=None, raise_on_error=True):
raise NotImplementedError('Database engine has no create_engine() method')

def connect(self):
Expand Down
1 change: 1 addition & 0 deletions alerta/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
DATABASE_URL = MONGO_URI # default: MongoDB
DATABASE_NAME = MONGO_DATABASE or POSTGRES_DB
DATABASE_RAISE_ON_ERROR = MONGO_RAISE_ON_ERROR # True - terminate, False - ignore and continue
DATABASE_SCHEMA = 'public' # default: None to use default schema

# Search
DEFAULT_FIELD = 'text' # default field if no search prefix specified (Postgres only)
Expand Down
2 changes: 1 addition & 1 deletion alerta/sql/schema.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'history') THEN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'history' AND typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema())) THEN
CREATE TYPE history AS (
id text,
event text,
Expand Down
1 change: 1 addition & 0 deletions alerta/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def get_user_config():
# Use app config for DATABASE_URL if no env var from above override it
config['DATABASE_URL'] = get_config('DATABASE_URL', default=database_url, type=str, config=config)
config['DATABASE_NAME'] = get_config('DATABASE_NAME', default=None, type=str, config=config)
config['DATABASE_SCHEMA'] = get_config('DATABASE_SCHEMA', default='public', type=str, config=config)

config['AUTH_REQUIRED'] = get_config('AUTH_REQUIRED', default=None, type=bool, config=config)
config['AUTH_PROVIDER'] = get_config('AUTH_PROVIDER', default=None, type=str, config=config)
Expand Down