Setting things up so it's easy to switch databases using a local configuration file (still works with environment variables)

Swtiched from a "joinedload" to a "selectinload" which removes a problem with groupby columns in Postgres and sqlite. (https://docs.sqlalchemy.org/en/14/orm/loading_relationships.html#selectin-eager-loading)
This commit is contained in:
Dan 2022-12-05 12:05:52 -05:00
parent 1e86345a33
commit 43bc82163e
3 changed files with 22 additions and 15 deletions

View File

@ -14,13 +14,13 @@ class ConfigurationError(Exception):
def setup_database_uri(app: Flask) -> None: def setup_database_uri(app: Flask) -> None:
"""Setup_database_uri.""" """Setup_database_uri."""
if os.environ.get("SPIFFWORKFLOW_BACKEND_DATABASE_URI") is None: if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_URI") is None:
database_name = f"spiffworkflow_backend_{app.config['ENV_IDENTIFIER']}" database_name = f"spiffworkflow_backend_{app.config['ENV_IDENTIFIER']}"
if os.environ.get("SPIFF_DATABASE_TYPE") == "sqlite": if app.config.get("SPIFF_DATABASE_TYPE") == "sqlite":
app.config[ app.config[
"SQLALCHEMY_DATABASE_URI" "SQLALCHEMY_DATABASE_URI"
] = f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3" ] = f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3"
elif os.environ.get("SPIFF_DATABASE_TYPE") == "postgres": elif app.config.get("SPIFF_DATABASE_TYPE") == "postgres":
app.config[ app.config[
"SQLALCHEMY_DATABASE_URI" "SQLALCHEMY_DATABASE_URI"
] = f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}" ] = f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}"
@ -33,7 +33,7 @@ def setup_database_uri(app: Flask) -> None:
"SQLALCHEMY_DATABASE_URI" "SQLALCHEMY_DATABASE_URI"
] = f"mysql+mysqlconnector://root:{db_pswd}@localhost/{database_name}" ] = f"mysql+mysqlconnector://root:{db_pswd}@localhost/{database_name}"
else: else:
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get( app.config["SQLALCHEMY_DATABASE_URI"] = app.config.get(
"SPIFFWORKFLOW_BACKEND_DATABASE_URI" "SPIFFWORKFLOW_BACKEND_DATABASE_URI"
) )
@ -73,9 +73,6 @@ def setup_config(app: Flask) -> None:
else: else:
app.config.from_pyfile(f"{app.instance_path}/config.py", silent=True) app.config.from_pyfile(f"{app.instance_path}/config.py", silent=True)
setup_database_uri(app)
setup_logger(app)
app.config["PERMISSIONS_FILE_FULLPATH"] = None app.config["PERMISSIONS_FILE_FULLPATH"] = None
if app.config["SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME"]: if app.config["SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME"]:
app.config["PERMISSIONS_FILE_FULLPATH"] = os.path.join( app.config["PERMISSIONS_FILE_FULLPATH"] = os.path.join(
@ -92,5 +89,8 @@ def setup_config(app: Flask) -> None:
if app.config["BPMN_SPEC_ABSOLUTE_DIR"] is None: if app.config["BPMN_SPEC_ABSOLUTE_DIR"] is None:
raise ConfigurationError("BPMN_SPEC_ABSOLUTE_DIR config must be set") raise ConfigurationError("BPMN_SPEC_ABSOLUTE_DIR config must be set")
setup_database_uri(app)
setup_logger(app)
thread_local_data = threading.local() thread_local_data = threading.local()
app.config["THREAD_LOCAL_DATA"] = thread_local_data app.config["THREAD_LOCAL_DATA"] = thread_local_data

View File

@ -60,3 +60,7 @@ SENTRY_TRACES_SAMPLE_RATE = environ.get(
SPIFFWORKFLOW_BACKEND_LOG_LEVEL = environ.get( SPIFFWORKFLOW_BACKEND_LOG_LEVEL = environ.get(
"SPIFFWORKFLOW_BACKEND_LOG_LEVEL", default="info" "SPIFFWORKFLOW_BACKEND_LOG_LEVEL", default="info"
) )
# Datbase Configuration
SPIFF_DATABASE_TYPE =environ.get("SPIFF_DATABASE_TYPE", default="mysql") # can also be sqlite, postgres
SPIFFWORKFLOW_BACKEND_DATABASE_URI=environ.get("SPIFFWORKFLOW_BACKEND_DATABASE_URI", default=None) # Overide above with specific sqlalchymy connection string.

View File

@ -30,7 +30,7 @@ from SpiffWorkflow.task import TaskState
from sqlalchemy import and_ from sqlalchemy import and_
from sqlalchemy import asc from sqlalchemy import asc
from sqlalchemy import desc from sqlalchemy import desc
from sqlalchemy.orm import joinedload from sqlalchemy.orm import selectinload
from spiffworkflow_backend.exceptions.process_entity_not_found_error import ( from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError, ProcessEntityNotFoundError,
@ -814,7 +814,7 @@ def process_instance_list(
process_instance_query = ProcessInstanceModel.query process_instance_query = ProcessInstanceModel.query
# Always join that hot user table for good performance at serialization time. # Always join that hot user table for good performance at serialization time.
process_instance_query = process_instance_query.options( process_instance_query = process_instance_query.options(
joinedload(ProcessInstanceModel.process_initiator) selectinload(ProcessInstanceModel.process_initiator)
) )
if report_filter.process_model_identifier is not None: if report_filter.process_model_identifier is not None:
@ -928,6 +928,7 @@ def process_instance_list(
UserGroupAssignmentModel.user_id == g.user.id UserGroupAssignmentModel.user_id == g.user.id
) )
try:
process_instances = ( process_instances = (
process_instance_query.group_by(ProcessInstanceModel.id) process_instance_query.group_by(ProcessInstanceModel.id)
.order_by( .order_by(
@ -935,6 +936,8 @@ def process_instance_list(
) )
.paginate(page=page, per_page=per_page, error_out=False) .paginate(page=page, per_page=per_page, error_out=False)
) )
except Exception as e:
print(e)
results = list( results = list(
map( map(