Skip to content

Copy Children

valhuber edited this page Apr 25, 2022 · 4 revisions

API Logic Server Example

The API Logic Server sample app includes a simple (no nesting) example of copy_children.

Scenario: Clone Existing Order

  Scenario: Clone Existing Order
   Given Shipped Order
   When Cloning Existing Order
   Then Logic Copies ClonedFrom OrderDetails

Tests - and their logic - are transparent.. click to see Logic

   

Logic Doc for scenario: Clone Existing Order

We create an order, setting CloneFromOrder.

This copies the CloneFromOrder OrderDetails to our new Order.

The copy operation is automated using logic_row.copy_children():

  1. place_order.feature defines the test

  2. place_order.py implements the test. It uses the API to Post an Order, setting CloneFromOrder to trigger the copy logic

  3. declare_logic.py implements the logic, by invoking logic_row.copy_children(). which defines which children to copy, here just OrderDetailList

Key Takeaway: parent references (e.g., OrderDetail.ShippedDate) automate chain-down multi-table transactions.

Key Takeaway: Automatic Reuse (design one, solve many)

Illustrate use of copy_children https://github.com/valhuber/LogicBank/wiki/Copy-Children

   

Rules Used in Scenario: Clone Existing Order

  Customer  
    1. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10be5b430>)  
    2. Constraint Function: None   
    3. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10bf4aaf0>)  
    4. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)  
  Order  
    5. Derive Order.AmountTotal as Sum(OrderDetail.Amount Where None)  
    6. Derive Order.OrderDetailCount as Count(<class 'database.models.OrderDetail'> Where None)  
    7. RowEvent Order.clone_order()   
  OrderDetail  
    8. Derive OrderDetail.Amount as Formula (1): as_expression=lambda row: row.UnitPrice * row.Qua [...]  
    9. Derive OrderDetail.ShippedDate as Formula (2): row.Order.ShippedDate  
    10. Derive OrderDetail.UnitPrice as Copy(Product.UnitPrice)  
  Product  
    11. Derive Product.UnitsShipped as Sum(OrderDetail.Quantity Where <function declare_logic.<locals>.<lambda> at 0x10bf4a8b0>)  
    12. Derive Product.UnitsInStock as Formula (1): <function>  
  

Logic Log in Scenario: Clone Existing Order

Logic Phase:		ROW LOGIC(session=0x10c7ba610) (sqlalchemy before_flush)			 - 2022-04-21 20:32:47,044 - logic_logger - INF
..Order[None] {Insert - client} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipPostalCode: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: None, OrderDetailCount: None, CloneFromOrder: 10643  row: 0x10c7ba4f0  session: 0x10c7ba610  ins_upd_dlt: ins - 2022-04-21 20:32:47,044 - logic_logger - INF
....Customer[ALFKI] {Update - Adjusting Customer: UnpaidOrderCount, OrderCount} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: 2102.0000000000, CreditLimit: 2300.0000000000, OrderCount:  [15-->] 16, UnpaidOrderCount:  [10-->] 11  row: 0x10c7bae50  session: 0x10c7ba610  ins_upd_dlt: upd - 2022-04-21 20:32:47,053 - logic_logger - INF
....OrderDetail[None] {warning: Order (OrderId not None... fixing} Id: None, OrderId:  [None-->] 10643, ProductId:  [None-->] 28, UnitPrice: None, Quantity:  [None-->] 15, Discount:  [None-->] 0.25, Amount: None, ShippedDate: None  row: 0x10c7ba1c0  session: 0x10c7ba610  ins_upd_dlt: ins - 2022-04-21 20:32:47,057 - logic_logger - INF
....OrderDetail[None] {Insert - Copy Children OrderDetailList} Id: None, OrderId: None, ProductId:  [None-->] 28, UnitPrice: None, Quantity:  [None-->] 15, Discount:  [None-->] 0.25, Amount: None, ShippedDate: None  row: 0x10c7ba1c0  session: 0x10c7ba610  ins_upd_dlt: ins - 2022-04-21 20:32:47,058 - logic_logger - INF
....OrderDetail[None] {copy_rules for role: Product - UnitPrice} Id: None, OrderId: None, ProductId:  [None-->] 28, UnitPrice:  [None-->] 45.6000000000, Quantity:  [None-->] 15, Discount:  [None-->] 0.25, Amount: None, ShippedDate: None  row: 0x10c7ba1c0  session: 0x10c7ba610  ins_upd_dlt: ins - 2022-04-21 20:32:47,060 - logic_logger - INF
....OrderDetail[None] {Formula Amount} Id: None, OrderId: None, ProductId:  [None-->] 28, UnitPrice:  [None-->] 45.6000000000, Quantity:  [None-->] 15, Discount:  [None-->] 0.25, Amount:  [None-->] 684.0000000000, ShippedDate: None  row: 0x10c7ba1c0  session: 0x10c7ba610  ins_upd_dlt: ins - 2022-04-21 20:32:47,061 - logic_logger - INF
......Product[28] {Update - Adjusting Product: UnitsShipped} Id: 28, ProductName: Rössle Sauerkraut, SupplierId: 12, CategoryId: 7, QuantityPerUnit: 25 - 825 g cans, UnitPrice: 45.6000000000, UnitsInStock: 26, UnitsOnOrder: 0, ReorderLevel: 0, Discontinued: 1, UnitsShipped:  [0-->] 15  row: 0x10c7a3700  session: 0x10c7ba610  ins_upd_dlt: upd - 2022-04-21 20:32:47,062 - logic_logger - INF
......Product[28] {Formula UnitsInStock} Id: 28, ProductName: Rössle Sauerkraut, SupplierId: 12, CategoryId: 7, QuantityPerUnit: 25 - 825 g cans, UnitPrice: 45.6000000000, UnitsInStock:  [26-->] 11, UnitsOnOrder: 0, ReorderLevel: 0, Discontinued: 1, UnitsShipped:  [0-->] 15  row: 0x10c7a3700  session: 0x10c7ba610  ins_upd_dlt: upd - 2022-04-21 20:32:47,063 - logic_logger - INF
......Order[None] {Update - Adjusting Order: AmountTotal, OrderDetailCount} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipPostalCode: None, ShipCountry: None, AmountTotal:  [None-->] 684.0000000000, Country: None, City: None, Ready: None, OrderDetailCount:  [None-->] 1, CloneFromOrder: 10643  row: 0x10c7ba4f0  session: 0x10c7ba610  ins_upd_dlt: upd - 2022-04-21 20:32:47,065 - logic_logger - INF
........Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance:  [2102.0000000000-->] 2786.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11  row: 0x10c7bae50  session: 0x10c7ba610  ins_upd_dlt: upd - 2022-04-21 20:32:47,067 - logic_logger - INF
........Customer[ALFKI] {Constraint Failure: balance (2786.0000000000) exceeds credit (2300.0000000000)} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance:  [2102.0000000000-->] 2786.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11  row: 0x10c7bae50  session: 0x10c7ba610  ins_upd_dlt: upd - 2022-04-21 20:32:47,068 - logic_logger - INF

Clone Project

Observe how the which_children argument enables you to copy children of children:

For this database: