DB Plan
Often, your extension may rely on certain information existing in the database to run appropriately. For instance, perhaps you are writing a login interrupt that expects a disclaimer to appear. Or perhaps you want to store text in the database for easy retrieval and update.
Whatever the reason, if you would like to pre-populate the database during extension installation, you want to know about our DbPlan class. Technically this operation happens at the tail end of installation, so your DbPlan can rely on data existing in the database already, such as the FormName or WedgeAddressConfigs.
DB Plans are comprised of one or more InstallSteps, and referenced in an extension’s DbPlan variable.
If you use the default extension built with q2 create_extension
entrypoint, these will live in
<your_extension>/install/db_plan.py
and look something like this:
from q2_sdk.core.install_steps import DbPlan as BaseDbPlan
from q2_sdk.core import install_steps
class DbPlan(BaseDbPlan):
def __init__(self):
"""
It is often necessary to configure the database with information
for an extension to run appropriately. This is your home to do so.
Each of these attributes corresponds to a table (or set of tables) in the
database. Instead of forcing all Antilles users to learn the
database structure of Q2, we've opted for this handy abstraction.
"""
super().__init__()
self.ui_text_prefix = 'AccountDashboard' # Will be used for all self.ui_text_elements
# self.send_account_list = True # Populate self.account_list when HQ calls the extension
# self.send_account_details = True # Populate HADE data on accounts in self.account_list
# self.wedge_payload_stored_proc = None # Run a given Stored Procedure to manipulate the call shape from HQ
# self.insight_features = [] # Run a list of Insight API Features as part of the install (Custom stored procedures)
# self.audit_actions = [install_steps.AuditAction()]
# self.data_feeds = [install_steps.DataFeed()]
# ...
Note
Depending on your version of the SDK, the actual options available in BaseDbPlan may vary. Typing self.
or
generating a new extension will have the full list available in your codebase.
Let’s say we wanted to save some text into the database. We would first find the appropriate line
(self.ui_text_elements
), and replace it with something like this:
self.ui_text_elements = [
install_steps.UiTextElement(
'myTextElement', # Short Name
'Contains text for my extension', # Description
'Radical!' # Text Value
)
]
Now, when we run q2 install
the database will be populated with these values.
For a full list of install_vars, refer to Install Steps in the Caliper Class Reference section.
Custom Install Steps
There may be times when the install steps provided by the SDK don’t quite meet your needs. That is why you can inherit from the SDKs install step classes, including the Install Steps Base. If any of your install steps in the DbPlan are dependant on any kind of logic it is best to put that logic into your own child install step class. Then you reference your custom class inside the DbPlan just like it was one provided by the SDK.
Example: A custom install step that initializes wedge config with different values based on the selected core:
import json
from q2_sdk.core.install_steps import db_plan
from q2_sdk.core.install_steps.base import InstallStep, InstallStepAttribute
from q2_sdk.hq.db.form import Form
class DbPlan(db_plan.DbPlan):
def __init__(self):
super().__init__()
self.ui_text_prefix = "MyExtensionName"
self.init_config = [InitializeConfig(form_short_name='MyExtensionName')]
class InitializeConfig(InstallStep):
def __init__(self, form_short_name: str):
super().__init__()
self.form_short_name = InstallStepAttribute(form_short_name, is_editable=True)
async def install(self):
# Fetch the specified form from the DB
form = await Form(
logger=self.logger,
hq_credentials=self.hq_credentials
).get_by_name(self.form_short_name.value)
# Parse wedge config JSON
config = json.loads(form.Config.text)
if "moneyMovementStyle" in config:
# Config is already set, don't override
return
# If CorePro was configured
if config["q2_core"]["name"] == "CorePro":
# Set our custom config
config["moneyMovementStyle"] = "fancy"
else:
config["moneyMovementStyle"] = "slightly-less-fancy"
# Update the form in the DB
await Form(self.logger).update(
short_name=form.ShortName.text,
url=form.Url.text,
config=config,
account_rights_bit_flag=int(form.AccountRightsBitFlag.text),
)