Package: logicbank
Logic Bank governs SQLAlchemy
update transaction logic - multi-table derivations, constraints,
and actions such as sending mail or messages. Logic consists of both:Rules - 40Xmore concise
using a spreadsheet-like paradigm, andPython - control and extensibility,using standard tools and techniquesThe example described below is atypicalexample of multi-table logic.You may find it helpful to begin withthis Tutorial, using a basic example.Update - Jan 26, 2021:You can use LogicBank for your ownexistingprojects.  Fornewprojects, the recommended approach isApiLogicServer- create a complete logic-enabled JSON:API for your database, and a admin app, with 1 command.This readme contains:BackgroundWhy- problems addressedWhat- what are spreadsheet-like rulesHow- usage / operation overviewLogic Execution- sample transaction execution, reuse and scalabilityInstant Web App- built usingFlask App Builder QuickstartInstall Instructions- of Python and Logic Bank, with verify and run instructionsProject InformationBackgroundWhy - Simple Cocktail-Napkin Spec Explodes into Massive Legacy CodeIf you've coded backend database logic - multi-table derivations and constraints -
you know how much work it is, and how tedious.  Whether you code it in
triggers and stored procedures, in ORM events, or UI controllers, it's a lot:
typically nearly half the effort for a database project.It's also incredibly repetitive - you often get the feeling you're doing the same thing over and over.And you're right.  It's because backend logic follows patterns of "what" is supposed to happen.
And your code is the "how".  Suddenly, a simple cocktail napkin specification explodes into a massive amount of legacy code:Logic Bank was designed to make the cocktail napkin specexecutable.What - Declare Spreadsheet-like Rules - 40X More ConciseLogic Bank introduces rules that are 40X more concise than legacy code.
The 5 rules below (lines 40-49) express the same logic as 200 lines of code(see them here).  That's because rules are all about "what"
-- spreadsheet-like expressions that automate the tedious "how":Standard Python - Declare, Extend, ManageLogic Bank is fully integrated with Python:Declarerules in Python as shown above (more details in How, below)Extendrules with Python (rule on line 51 invokes the Python function on line 32)Managelogic using your existing IDE (PyCharm, VSCode etc for code completion, debugging, etc),
and source control tools and proceduresTechnology Evaluation40X is...large- do these results hold in practice?
Seeherefor
additional background, and real world experience.How - Usage and Operation OverviewLogic Bank operates as shown above:Declare and Activate(see example above):a. Create adeclare_logicfunction (above, line 12),
and declare your rules usingRule.(e.g., with IDE code completion)b. After opening your database, callactivateto register your rules, and establish Logic Bank as
a listener for SQLAlchemybefore_flusheventsYour application operates as usual: makes calls onSQLAlchemyfor inserts, updates and deletes
and issuessession.commit()By bundling transaction logic into SQLAlchemy data access, your logic
is automatically shared, whether for hand-written code (Flask apps, APIs)TheLogic Bankengine handles SQLAlchemybefore_flushevents onMapped Tables, so executes when you issuesession.commit()The logic engine operates much like a spreadsheet:watchfor changes at the attribute levelreactby running rules that referenced changed attributes, which canchainto still other attributes that refer tothosechanges.  Note these might be in different tables,
providing automation formulti-table logicLogic does not apply to updates outside SQLAlchemy,
nor to SQLAlchemy batch updates or unmapped sql updates.Let's see how logic operates on a typical, multi-table transaction.Logic Execution: Add Order - Watch, React, ChainTheadd_orderexample illustrates howWatch / React / Chainoperates to
check the Credit Limit as each OrderDetail is inserted:TheOrderDetail.UnitPrice(copy, line 49) references Product, so inserts cause it to be copiedAmount(formula, line 48) watchesUnitPrice, so its new value recomputesAmountAmountTotal(sum, line 46) watchesAmount, soAmountTotalis adjusted (more on adjustment, below)Balance(sum, line 43) watchesAmountTotal, so it is adjustedAnd the Credit Limit constraint (line 40) is checked (exceptions are raised if constraints are violated, and the transaction is rolled back)All of the dependency management to see which attributes have changed,
logic ordering, the SQL commands to read and adjust rows, and the chaining
are fully automated by the engine, based solely on the rules above.Spreadsheet-like Automatic ReuseJust as a spreadsheet reacts
to inserts, updates and deletes to a summed column,
rules automateadding,deletingandupdatingorders.
This is how 5 rules represent the same logic as 200 lines of code.Check out more examples:Ship Orderillustratescascade, another form of multi-table logicBankingis a complex transaction using the command patternScalability: Automatic Prune / Optimize logicScalability requires more than clustering - SQLs must be pruned
and optimized.  For example, the balance rule:isprunedif only a non-referenced column is altered (e.g., Shipping Address)isoptimizedinto a 1-rowadjustmentupdate instead of an
expensive SQL aggregateFor more on how logic automates and optimizes multi-table transactions,click here.An Agile PerspectiveThe core tenant of agile isWorking software, driving collaboration, for rapid iterationsHere's how rules can help.Working SoftwareNowThe examples above illustrate how just a few rules can replacepages of code.Iteration - Automatic OrderingRules areself-ordering- they recognize their interdependencies,
and order their execution and database access (pruning, adjustments etc)
accordingly.  This means:order is independent - you can state the rules in any order
and get the same resultmaintenance is simple - just make changes, additions and deletions,
the engine will reorganize execution order and database access, automaticallyInstallationFirst, follow the instructions to verify / install Python, then install Logic Bank.Python InstallationThe first section below verifies whether your Python environment is current.
The following section explains how to install a current Python environment.Verify Pre-reqs: Python 3.8, virtualenv, pip3Ensure you have these pre-reqs:python --version
# requires 3.8 or higher (Relies on `from __future__ import annotations`, so requires Python 3.8)

pip --version
# version 19.2.3 or higher... you might be using pip3

pyenv --version
# 1.2.19 or higherInstall Python (if required)If you are missing any, install them as described here.  Skip this step if your pre-reqs are fine.To install Python:Python3.8Run the windows installerBe sure to specify "add Python to Path"On mac/Unix, considerusing homebrew, as describedherevirtualenv - seehere(e.g.,pip install virtualenv)on PC, seethese instructionsAn IDE - optional - any will do (I've usedPyCharmandVSCode, install noteshere), though different install / generate / run instructions apply for running programs.Issues?Try here.Install LogicBankThis procedure installs the Logic Bank source code, including
examples you can explore.To use Logic Bank in your own project:pip install LogicBankIn your IDE or Command Line:# optionally fork, and then (WARNING - remove hyphens if you download the zip)
git clone https://github.com/valhuber/LogicBank.git
cd LogicBank
# windows: python -m venv venv
virtualenv venv
# For windows: .\venv\Scripts\activate
source venv/bin/activate
pip install -r requirements.txtWarning -if you just download the zip,be sureto remove the hyphen from the name.Warning -if you use an IDE, be sure to activate the virtual environment, and verify you are running a proper version of Python.Verify and RunRun thenw/testsRun thenw/testsprograms under your IDE or the
command line; start withtest_add_orderandtest_upd_order_shipped,and see thewalk-throughs here.
The tests useunittest- you can run them as follows:cd examples/nw/tests
python -m unittest test_add_order.py
python test_add_order.py  # or, run it like this

python -m unittest discover -p "test*.py"  # run all testsNote: the consolelogdepicts logic executionLog lines are long - consider copying them to a text
editor to view with / without word wrapOr, run in an IDE - they looklike this.Next StepsRun the TutorialFirst, run the10 minute Tutorial.
You will see how to create, run and debug a rule in a simple, running example.Explore Sample TransactionsThen, check out theExamples- note thenavigation baron the right.  Key samples:Ship Orderillustratescascade, another form of multi-table logicAllocationillustratesextensibility,
providing a reusable pattern for aproviderto allocate
to a set ofrecipientsBankingis a complex transaction using the command patternReferential Integrityillustrates referential integrity supportA good way to proceed is toClear the logRun the testReview the log, and the rules that drove the processingArticlesThere a few articles that provide some orientation to Logic Bank:Extensible Rules- defining new rule types, using PythonDeclarative- exploringmulti-statementdeclarative technologyAutomate Business Logic With Logic Bank- general introduction, discussions of extensibility, manageability and scalabilityAgile Design Automation With Logic Bank- focuses on automation, design flexibility and agile iterationsSee also theLogicBankExamplesprojectTheLogic Bank Examples(setup instructions here)contains the same examples, butnotthelogic_bankengine source code.
It uses the logic engine viapip install, as you would for your own projects:pip install logicbankThis isnot required here, and requires the same
pre-reqs noted aboveProject InformationRevisionsRevisionsare described here.What's in the projectLogic Bank consists of:Several test database systems -nw,banking,referential_integrityandpayment_allocation;
these containDatabasessqlite (no install required) and modelsTest foldersthat run key transactions - just run the scripts
(note the logs)Logic- rules (and fornw,
the manuallegacycode for contrast to rules)Thenwsample illustrates comparisons of Business logic, bothby codeand by rules (shown above).Thelogic_bankengine source codeInternalsTo explore:Clickherefor install / operations proceduresClickherefor a
short overview of internal logic executionAcknowledgementsThere are many to thank:Tyler Band, for testing and the Banking exampleMax Tardiveau, for testingNishanth Shyamsundar, for PC testingMichael Holleran, for collaborationMike Bayer, for suggestions on leveraging Python typing and remarkable responsivenessAchim Götz, for reporting an issue in FAB Quick Start use of Logic BaseGloria, for many reviews... and golden patience