Logic: Rule Types, Patterns
TL;DR - Logic: multi-table derivations and constraints, using Rules and Python
Logic addresses multi-table derivations and constraints, using Rules and Python.
Rules are:
- Declared in your IDE - 40X more concise - with GenAI or Code Completion
- Activated on server start
- Executed - automatically - on updates (using SQLAlchemy events)
- Debugged in your IDE, and with the console log
Rule Types
The table shows excerpts only; see the ApiLogicProject
(Northwind) sample for full syntax.
Rule | Summary | Example | Notes |
---|---|---|---|
Constraint | Boolean function must be True else transaction rolled back |
row.Balance <= row.CreditLimit row.Salary >= Decimal('1.20') * old_row.Salary |
Multi-fieldold_row |
Formula | Function computes column value | row.UnitPrice * row.Quantity row.OrderHeader.ShippedDate |
lambda, or function Parent (OrderHeader) references |
Sum | Derive parent-attribute as sum of designated child attribute; optional child qualification | Rule.sum(derive=Customer.Balance, as_sum_of=Order.AmountTotal,where=lambda row: row.ShippedDate is None) |
Parent attribute can be hybrid (virtual) scalable: pruning, adjustment |
Count | Derive parent-attribute as count of child rows; optional child qualification | Rule.count(derive=Order.OrderDetailCount, as_count_of=OrderDetail) |
counts are useful as child existence checks |
Copy | Child value set from Parent | OrderDetail.ProductPrice = copy(Product.Price) |
Unlike formula references, parent changes are not propagated e.g, Order totals for Monday are not affected by a Tuesday price increase |
Event | Python Function | on insert, call congratulate_sales_rep |
See Extensibility for a information on early, row and commit events |
Parent Check | Ensure Parent row exists | Orders must have a Customer | See Referential Integrity |
Allocation | Allocate a provider amount to recipients | allocate a payment to outstanding orders | See Allocation for an example |
Copy Row | Create child row by copying parent | audit Employee Salary changes to EmployeeAudit | See Rule Extensibility |
Declaring Rules
Rules are declared in your IDE, using GenAI or Code Completion. Edit the file declare_logic.py
in your project, or, one of the files in the discovery directory.
With GenAI Logic Automation
You can use Natural Language to create logic during project creation, or for existing projects. For more information, see here.
With CoPilot
If you have Copilot installed, you can use GenAI to create rules. Enter your GenAI prompt, and use Copilot's Insert at Cursor button to pasted into declare_logic.py
You will typically need to make some small changes, such as the import statements.
In the example below, we have pasted the prompt from the GenAI Automation prompt used to create the system. You can of course enter new text, or paste from any source.
With Code Completion
You can also use Code Completion to add rules, and their arguments.
Iterative Rules
Logic definition is an incremental process. You can start with a few rules, and add more as needed. There is no need to define all rules at once, or rebuild the project.
Note rules are automatically ordered and invoked, so you can add new ones in any location.
Similarly, you can change rules without worrying about the order of execution.
Learning Rules
Inside the larger process above, here is the best way to learn how to use rules:
-
Rule Summary: review the table above; there are a small number of rules, since their power lies in chaining
- Alert: Logic consists of rules and Python. You will quickly learn to use logic events; focus on the rules as the preferred approach, using Python (events, etc) as a fallback.
-
Review the Rule Patterns, below
-
Use the case study approach to learn about using rules, by exploring the examples in the report, below.
-
Be aware of Rule Extensibility.
Pre-req: before learning rules, use the Tutorial to familiarize yourself with basic capabilities and procedures.
Rule Patterns
Pattern | Notes | Example |
---|---|---|
Chain Up | parent sums and counts mean that child row changes can adjust parents | Derive Balance |
Constrain a Derived Result | constraints may require derived values | Balance < creditLimit |
Chain Down | child copy and parent references mean that parent row changes can cascade to children | Ship Order |
State Transition Logic | old_row useful comparing old/current values |
Meaningful Raise |
Counts as Existence Checks | Use counts to check if any children exist | Don't Ship Empty Orders |
Auditing | Note the Copy Row rule (and alternatives) | Salary Audit |
Ready Flag | Multi-session editing, then , when ready... adjust related data / enforce constraints |
Make Order Ready |
Events for Lib Access | Events enable Python, use of standard libs (e.g., Kafka) | Ship Order |
Case Study
The best way to learn the rules is by a Case Study approach:
-
Print this page, for reference
-
Print the Database Diagram
- Most of the examples are drawn from this database
-
For each Rule Pattern, above:
-
Click the Example link in the table above to open the Behave Logic Report
- Aside: later, you can prepare such documentation for your own projects, (like this).
-
Review the Scenario -- take these as your requirements
-
Spend 5 minutes (perhaps in pairs) and cocktail-napkin design your solution, using
- The data model diagram
- List of Rule Types, and
- Rule Patterns
-
Reveal the solution: open the disclosure box: "Tests - and their logic - are transparent.. click to see Logic"
-