|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "# Homework 8: Transactions\n", |
| 8 | + "\n", |
| 9 | + "Prior to working on this homework, execute [004-DatabaseSales.ipynb](004-DatabaseSales.ipynb) to create the classic sales database.\n", |
| 10 | + "\n", |
| 11 | + "Create the python function `place_order`, which accepts a list of products, their quantities, the customer id, the employee id, and the payment amount. It should use a transaction to place an order. You cannot use SQL magic; use python libraries such as `pymysql` or `datajoint` (or possibly others if you prefer). The order consists of inserting an order into `Order`, all its items into `Order.Item`, and the corresponding payment into `Payment`. The function should through an error if the total on the payment does not match the total price of the items. The entire transaction should rollback should an interruption or error occur before the entire transaction completes.\n", |
| 12 | + "\n", |
| 13 | + "Play with the function enough to convince yourself that it implements transactions correctly. To grade, the instructor will review the code for correctness.\n", |
| 14 | + "\n" |
| 15 | + ] |
| 16 | + }, |
| 17 | + { |
| 18 | + "cell_type": "code", |
| 19 | + "execution_count": 4, |
| 20 | + "metadata": {}, |
| 21 | + "outputs": [ |
| 22 | + { |
| 23 | + "name": "stdout", |
| 24 | + "output_type": "stream", |
| 25 | + "text": [ |
| 26 | + "The sql extension is already loaded. To reload it, use:\n", |
| 27 | + " %reload_ext sql\n" |
| 28 | + ] |
| 29 | + } |
| 30 | + ], |
| 31 | + "source": [ |
| 32 | + "import pymysql\n", |
| 33 | + "pymysql.install_as_MySQLdb()\n", |
| 34 | + "%load_ext sql\n", |
| 35 | + "%config SqlMagic.autocommit=True\n", |
| 36 | + "%sql mysql://root:[email protected]" |
| 37 | + ] |
| 38 | + }, |
| 39 | + { |
| 40 | + "cell_type": "code", |
| 41 | + "execution_count": 5, |
| 42 | + "metadata": {}, |
| 43 | + "outputs": [ |
| 44 | + { |
| 45 | + "data": { |
| 46 | + "image/svg+xml": [ |
| 47 | + "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"247pt\" height=\"356pt\" viewBox=\"0.00 0.00 246.50 356.00\">\n", |
| 48 | + "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 352)\">\n", |
| 49 | + "<title>%3</title>\n", |
| 50 | + "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-352 242.5,-352 242.5,4 -4,4\"/>\n", |
| 51 | + "<!-- 0 -->\n", |
| 52 | + "<g id=\"node1\" class=\"node\">\n", |
| 53 | + "<title>0</title>\n", |
| 54 | + "<ellipse fill=\"#ff8800\" fill-opacity=\"0.501961\" stroke=\"#ff8800\" stroke-opacity=\"0.501961\" cx=\"125.5\" cy=\"-201.5\" rx=\"2\" ry=\"2\"/>\n", |
| 55 | + "<text text-anchor=\"middle\" x=\"125.5\" y=\"-201.2\" font-family=\"arial\" font-size=\"1.00\" fill=\"#ff8800\" fill-opacity=\"0.501961\">0</text>\n", |
| 56 | + "</g>\n", |
| 57 | + "<!-- Report -->\n", |
| 58 | + "<g id=\"node3\" class=\"node\">\n", |
| 59 | + "<title>Report</title>\n", |
| 60 | + "<g id=\"a_node3\"><a xlink:title=\"→ Employee\r------------------------------\r→ Employee.proj(reports_to="employee_number")\r\">\n", |
| 61 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"152,-161 99,-161 99,-126 152,-126 152,-161\"/>\n", |
| 62 | + "<text text-anchor=\"middle\" x=\"125.5\" y=\"-140.4\" font-family=\"arial\" font-size=\"12.00\" fill=\"darkgreen\">Report</text>\n", |
| 63 | + "</a>\n", |
| 64 | + "</g>\n", |
| 65 | + "</g>\n", |
| 66 | + "<!-- 0->Report -->\n", |
| 67 | + "<g id=\"edge1\" class=\"edge\">\n", |
| 68 | + "<title>0->Report</title>\n", |
| 69 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-dasharray=\"5,2\" stroke-opacity=\"0.250980\" d=\"M125.5,-199.12C125.5,-193.93 125.5,-175.22 125.5,-161.13\"/>\n", |
| 70 | + "</g>\n", |
| 71 | + "<!-- 1 -->\n", |
| 72 | + "<g id=\"node2\" class=\"node\">\n", |
| 73 | + "<title>1</title>\n", |
| 74 | + "<ellipse fill=\"#ff8800\" fill-opacity=\"0.501961\" stroke=\"#ff8800\" stroke-opacity=\"0.501961\" cx=\"201.5\" cy=\"-201.5\" rx=\"2\" ry=\"2\"/>\n", |
| 75 | + "<text text-anchor=\"middle\" x=\"201.5\" y=\"-201.2\" font-family=\"arial\" font-size=\"1.00\" fill=\"#ff8800\" fill-opacity=\"0.501961\">1</text>\n", |
| 76 | + "</g>\n", |
| 77 | + "<!-- Customer -->\n", |
| 78 | + "<g id=\"node11\" class=\"node\">\n", |
| 79 | + "<title>Customer</title>\n", |
| 80 | + "<g id=\"a_node11\"><a xlink:title=\"customer_number \r------------------------------\rcustomer_name \rcontact_last_name \rcontact_first_name \rphone \rpostal_line1 \rpostal_line2=null \rcity \rstate=null \rpostal_code=null \rcountry \r→ [nullable] Employee.proj(sales_rep="employee_number")\rcredit_limit=null \r\">\n", |
| 81 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"238.5,-161 170.5,-161 170.5,-126 238.5,-126 238.5,-161\"/>\n", |
| 82 | + "<text text-anchor=\"start\" x=\"178.5\" y=\"-141.4\" font-family=\"arial\" text-decoration=\"underline\" font-size=\"12.00\" fill=\"darkgreen\">Customer</text>\n", |
| 83 | + "</a>\n", |
| 84 | + "</g>\n", |
| 85 | + "</g>\n", |
| 86 | + "<!-- 1->Customer -->\n", |
| 87 | + "<g id=\"edge2\" class=\"edge\">\n", |
| 88 | + "<title>1->Customer</title>\n", |
| 89 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-dasharray=\"5,2\" stroke-opacity=\"0.250980\" d=\"M201.57,-199.12C201.85,-193.93 202.85,-175.22 203.61,-161.13\"/>\n", |
| 90 | + "</g>\n", |
| 91 | + "<!-- ProductLine -->\n", |
| 92 | + "<g id=\"node4\" class=\"node\">\n", |
| 93 | + "<title>ProductLine</title>\n", |
| 94 | + "<g id=\"a_node4\"><a xlink:title=\"product_line \r------------------------------\rtextDescription=null \rhtmlDescription=null \rimage=null \r\">\n", |
| 95 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"81,-161 0,-161 0,-126 81,-126 81,-161\"/>\n", |
| 96 | + "<text text-anchor=\"start\" x=\"8\" y=\"-141.4\" font-family=\"arial\" text-decoration=\"underline\" font-size=\"12.00\" fill=\"darkgreen\">ProductLine</text>\n", |
| 97 | + "</a>\n", |
| 98 | + "</g>\n", |
| 99 | + "</g>\n", |
| 100 | + "<!-- Product -->\n", |
| 101 | + "<g id=\"node5\" class=\"node\">\n", |
| 102 | + "<title>Product</title>\n", |
| 103 | + "<g id=\"a_node5\"><a xlink:title=\"product_code \r------------------------------\rproduct_name \r→ ProductLine\rproduct_scale \rvendor \rproduct_description \rquantity_in_stock \rbuy_price \rMSRP \r\">\n", |
| 104 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"75.5,-90 17.5,-90 17.5,-55 75.5,-55 75.5,-90\"/>\n", |
| 105 | + "<text text-anchor=\"start\" x=\"25.5\" y=\"-70.4\" font-family=\"arial\" text-decoration=\"underline\" font-size=\"12.00\" fill=\"darkgreen\">Product</text>\n", |
| 106 | + "</a>\n", |
| 107 | + "</g>\n", |
| 108 | + "</g>\n", |
| 109 | + "<!-- ProductLine->Product -->\n", |
| 110 | + "<g id=\"edge3\" class=\"edge\">\n", |
| 111 | + "<title>ProductLine->Product</title>\n", |
| 112 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-dasharray=\"5,2\" stroke-opacity=\"0.250980\" d=\"M41.95,-125.8C42.9,-114.95 44.12,-100.87 45.06,-90.05\"/>\n", |
| 113 | + "</g>\n", |
| 114 | + "<!-- Order.Item -->\n", |
| 115 | + "<g id=\"node7\" class=\"node\">\n", |
| 116 | + "<title>Order.Item</title>\n", |
| 117 | + "<g id=\"a_node7\"><a xlink:title=\"→ Order\r→ Product\r------------------------------\rquantity \rprice \rorder_line_number \r\">\n", |
| 118 | + "<polygon fill=\"transparent\" stroke=\"transparent\" points=\"236,-19 173,-19 173,0 236,0 236,-19\"/>\n", |
| 119 | + "<text text-anchor=\"middle\" x=\"204.5\" y=\"-7\" font-family=\"arial\" font-size=\"10.00\">Order.Item</text>\n", |
| 120 | + "</a>\n", |
| 121 | + "</g>\n", |
| 122 | + "</g>\n", |
| 123 | + "<!-- Product->Order.Item -->\n", |
| 124 | + "<g id=\"edge4\" class=\"edge\">\n", |
| 125 | + "<title>Product->Order.Item</title>\n", |
| 126 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-opacity=\"0.250980\" d=\"M75.85,-60.17C106.73,-48.25 154.62,-29.76 182.44,-19.02\"/>\n", |
| 127 | + "</g>\n", |
| 128 | + "<!-- Payment -->\n", |
| 129 | + "<g id=\"node6\" class=\"node\">\n", |
| 130 | + "<title>Payment</title>\n", |
| 131 | + "<g id=\"a_node6\"><a xlink:title=\"→ Customer\rcheck_number \r------------------------------\rpayment_date \ramount \r\">\n", |
| 132 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"162.5,-90 98.5,-90 98.5,-55 162.5,-55 162.5,-90\"/>\n", |
| 133 | + "<text text-anchor=\"start\" x=\"106.5\" y=\"-70.4\" font-family=\"arial\" text-decoration=\"underline\" font-size=\"12.00\" fill=\"darkgreen\">Payment</text>\n", |
| 134 | + "</a>\n", |
| 135 | + "</g>\n", |
| 136 | + "</g>\n", |
| 137 | + "<!-- Order -->\n", |
| 138 | + "<g id=\"node8\" class=\"node\">\n", |
| 139 | + "<title>Order</title>\n", |
| 140 | + "<g id=\"a_node8\"><a xlink:title=\"order_number \r------------------------------\rorder_date \rrequired_date \rshipped_date=null \rstatus \rcomments=null \r→ Customer\r\">\n", |
| 141 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"228,-90 181,-90 181,-55 228,-55 228,-90\"/>\n", |
| 142 | + "<text text-anchor=\"start\" x=\"189\" y=\"-70.4\" font-family=\"arial\" text-decoration=\"underline\" font-size=\"12.00\" fill=\"darkgreen\">Order</text>\n", |
| 143 | + "</a>\n", |
| 144 | + "</g>\n", |
| 145 | + "</g>\n", |
| 146 | + "<!-- Order->Order.Item -->\n", |
| 147 | + "<g id=\"edge5\" class=\"edge\">\n", |
| 148 | + "<title>Order->Order.Item</title>\n", |
| 149 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-opacity=\"0.250980\" d=\"M204.5,-54.83C204.5,-43.26 204.5,-28.32 204.5,-19.08\"/>\n", |
| 150 | + "</g>\n", |
| 151 | + "<!-- Office -->\n", |
| 152 | + "<g id=\"node9\" class=\"node\">\n", |
| 153 | + "<title>Office</title>\n", |
| 154 | + "<g id=\"a_node9\"><a xlink:title=\"office_code \r------------------------------\rcity \rphone \rpostal_line1 \rpostal_line2=null \rstate=null \rcountry \rpostal_code \rterritory \r\">\n", |
| 155 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"186,-348 139,-348 139,-313 186,-313 186,-348\"/>\n", |
| 156 | + "<text text-anchor=\"start\" x=\"147\" y=\"-328.4\" font-family=\"arial\" text-decoration=\"underline\" font-size=\"12.00\" fill=\"darkgreen\">Office</text>\n", |
| 157 | + "</a>\n", |
| 158 | + "</g>\n", |
| 159 | + "</g>\n", |
| 160 | + "<!-- Employee -->\n", |
| 161 | + "<g id=\"node10\" class=\"node\">\n", |
| 162 | + "<title>Employee</title>\n", |
| 163 | + "<g id=\"a_node10\"><a xlink:title=\"employee_number \r------------------------------\rlast_name \rfirst_name \rextension \remail \r→ Office\rjob_title \r\">\n", |
| 164 | + "<polygon fill=\"#00ff00\" fill-opacity=\"0.188235\" stroke=\"#00ff00\" stroke-opacity=\"0.188235\" points=\"198,-277 127,-277 127,-242 198,-242 198,-277\"/>\n", |
| 165 | + "<text text-anchor=\"start\" x=\"135\" y=\"-257.4\" font-family=\"arial\" text-decoration=\"underline\" font-size=\"12.00\" fill=\"darkgreen\">Employee</text>\n", |
| 166 | + "</a>\n", |
| 167 | + "</g>\n", |
| 168 | + "</g>\n", |
| 169 | + "<!-- Office->Employee -->\n", |
| 170 | + "<g id=\"edge6\" class=\"edge\">\n", |
| 171 | + "<title>Office->Employee</title>\n", |
| 172 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-dasharray=\"5,2\" stroke-opacity=\"0.250980\" d=\"M162.5,-312.8C162.5,-301.95 162.5,-287.87 162.5,-277.05\"/>\n", |
| 173 | + "</g>\n", |
| 174 | + "<!-- Employee->0 -->\n", |
| 175 | + "<g id=\"edge7\" class=\"edge\">\n", |
| 176 | + "<title>Employee->0</title>\n", |
| 177 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-dasharray=\"5,2\" stroke-opacity=\"0.250980\" d=\"M151.4,-241.7C141.86,-227.26 129.19,-208.08 126.17,-203.51\"/>\n", |
| 178 | + "</g>\n", |
| 179 | + "<!-- Employee->1 -->\n", |
| 180 | + "<g id=\"edge8\" class=\"edge\">\n", |
| 181 | + "<title>Employee->1</title>\n", |
| 182 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-dasharray=\"5,2\" stroke-opacity=\"0.250980\" d=\"M174.2,-241.7C184.25,-227.26 197.61,-208.08 200.8,-203.51\"/>\n", |
| 183 | + "</g>\n", |
| 184 | + "<!-- Employee->Report -->\n", |
| 185 | + "<g id=\"edge9\" class=\"edge\">\n", |
| 186 | + "<title>Employee->Report</title>\n", |
| 187 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"2\" stroke-opacity=\"0.250980\" d=\"M157.48,-241.75C153.72,-229.36 148.42,-212.09 143.5,-197 139.56,-184.91 134.9,-171.33 131.3,-161.01\"/>\n", |
| 188 | + "</g>\n", |
| 189 | + "<!-- Customer->Payment -->\n", |
| 190 | + "<g id=\"edge10\" class=\"edge\">\n", |
| 191 | + "<title>Customer->Payment</title>\n", |
| 192 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-opacity=\"0.250980\" d=\"M186.59,-125.8C174.95,-114.95 159.85,-100.87 148.25,-90.05\"/>\n", |
| 193 | + "</g>\n", |
| 194 | + "<!-- Customer->Order -->\n", |
| 195 | + "<g id=\"edge11\" class=\"edge\">\n", |
| 196 | + "<title>Customer->Order</title>\n", |
| 197 | + "<path fill=\"none\" stroke=\"#000000\" stroke-width=\"0.75\" stroke-dasharray=\"5,2\" stroke-opacity=\"0.250980\" d=\"M204.5,-125.8C204.5,-114.95 204.5,-100.87 204.5,-90.05\"/>\n", |
| 198 | + "</g>\n", |
| 199 | + "</g>\n", |
| 200 | + "</svg>" |
| 201 | + ], |
| 202 | + "text/plain": [ |
| 203 | + "<datajoint.diagram.Diagram at 0x7f5c6c058f70>" |
| 204 | + ] |
| 205 | + }, |
| 206 | + "execution_count": 5, |
| 207 | + "metadata": {}, |
| 208 | + "output_type": "execute_result" |
| 209 | + } |
| 210 | + ], |
| 211 | + "source": [ |
| 212 | + "import datajoint as dj\n", |
| 213 | + "\n", |
| 214 | + "sales = dj.Schema('classicsales')\n", |
| 215 | + "sales.spawn_missing_classes()\n", |
| 216 | + "\n", |
| 217 | + "dj.Diagram(sales)" |
| 218 | + ] |
| 219 | + } |
| 220 | + ], |
| 221 | + "metadata": { |
| 222 | + "kernelspec": { |
| 223 | + "display_name": "Python 3", |
| 224 | + "language": "python", |
| 225 | + "name": "python3" |
| 226 | + }, |
| 227 | + "language_info": { |
| 228 | + "codemirror_mode": { |
| 229 | + "name": "ipython", |
| 230 | + "version": 3 |
| 231 | + }, |
| 232 | + "file_extension": ".py", |
| 233 | + "mimetype": "text/x-python", |
| 234 | + "name": "python", |
| 235 | + "nbconvert_exporter": "python", |
| 236 | + "pygments_lexer": "ipython3", |
| 237 | + "version": "3.9.17" |
| 238 | + } |
| 239 | + }, |
| 240 | + "nbformat": 4, |
| 241 | + "nbformat_minor": 2 |
| 242 | +} |
0 commit comments