Skip to content

Managing Rules

valhuber edited this page Dec 3, 2020 · 15 revisions

#Managing Rules

Don't

It's well to start off by remembering things you don't do with rules:

  • Order - unlike code where order is critical, rule execution is via system-discovered dependencies. When you change the logic, the execution order changes accordingly. This means you just add rules without worrying about ordering.
  • Call - you don't call the rules, the rule engine does. This means your logic always runs.
  • Optimize - SQLs are pruned and optimized for you (e.g., adjustments)

Favor Rules Over Code

New users will recognize Event rules immediately - they are a familiar metaphor (triggers etc). And you will certainly use them.

But rules are much more efficient of your time, so it pays - a lot - to spend the design time to search for a rule solution before you jump into code.

State the Requirement

Begin by stating the requirement, e.g., Check Credit. Then, define rules that implement the requirement.

Rule Diagrams

Rules are about the data, so it's useful to superimpose the rules on a database diagram:

Rule Discovery

The simplest way to discover rules is using your IDE, as described in the Logic Bank Tutorial.

Database Design

Rules depend on database design, so these concepts below are crucial.

Normalized

Normalize your database design as usual.

Performance Denormalizations

That said, you can get sometimes-enormous performance gains by introducing performance denormalizations for sum / count aggregates. See Denormalizations.

Relationships: DB, or Virtual

The interesting rules (sums, counts, parent references) depend on relationships. It's great to have these in the database, but if that's not possible, you can still define them in SQLAlchemy:

    # from nw/db/models.py, for Customer...
    OrderList = relationship("Order",
                             backref="Customer",
                             cascade="all, delete",
                             passive_deletes=True,  # means database RI will do the deleting
                             cascade_backrefs=True)

Columns as Rows does not work

A typical approach for extensibility is to define columns as rows, e.g., each column is a child row:

primary-key | col-name | value

Such columns are not visible to SQLAlchemy, or Logic Bank.

Rule Patterns

Rules are a different paradigm than code, and there are important patterns in their use.

Constrain a derived result

Counts as existence checks

State Transition Logic (old values)

Debug

Logic includes Python, not just Rules. You can set breakpoints and step in Python code, as usual.

Rule Logging

Rule Logging can reduce the need for tedious debug sessions.