HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Splitting out joined table data

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
joinedsplittingdataouttable

Problem

Consider the following segment of code:

# Fetch my orders
orders = repo.get_orders_for(self._customer[0])

if len(orders) > 0:
    current_order_no = -1
    for (order_number, quantity, pid) in orders:

        # Print new heading if needed
        if order_number is not current_order_no:
            print("Order #{}".format(order_number))
            current_order_no = order_number

        print("    Product #{}, ordered x{}".format(pid, quantity))


I feel like there's just a lot going on. I basically do a JOIN on two tables, and return some orders and their order_items. The JOIN obviously duplicates the order_number on several rows, so I need a way of telling them apart. Is there a better way of doing this in Python (actually, I'll accept any language answer for curiosity!) Or is it my way of joining that's evil?

For the curious, the SQL statement is:

SELECT OrderNumber, Quantity, Product_ProductId FROM `order` JOIN `orderitem` ON `order`.OrderNumber = Order_OrderNumber WHERE CustomerAccount_CustomerId=%s ORDER BY OrderNumber

Solution


  • You can use itertools.groupby to group the items by order number.



-
Don't use is to compare numbers. is checks object identity and the same number can be represented by different objects:

>>> a=1234
>>> b=1234
>>> a is b
False
>>> a=12
>>> b=12
>>> a is b
True


-
Checking if len(orders) > 0 before the for loop is redundant. If the list is empty the loop won't run even once.

Revised code:

from itertools import groupby
from operator import itemgetter

# Fetch my orders
orders = repo.get_orders_for(self._customer[0])

for order_number, items in groupby(orders, key=itemgetter(0)):
    print("Order #{}".format(order_number))
    for _, quantity, pid in items:
        print("    Product #{}, ordered x{}".format(pid, quantity))

Code Snippets

>>> a=1234
>>> b=1234
>>> a is b
False
>>> a=12
>>> b=12
>>> a is b
True
from itertools import groupby
from operator import itemgetter

# Fetch my orders
orders = repo.get_orders_for(self._customer[0])

for order_number, items in groupby(orders, key=itemgetter(0)):
    print("Order #{}".format(order_number))
    for _, quantity, pid in items:
        print("    Product #{}, ordered x{}".format(pid, quantity))

Context

StackExchange Code Review Q#83968, answer score: 4

Revisions (0)

No revisions yet.