Attempting to reflect a database

This is a clever way of saying: let's see if we can read the database schema using SQLAlchemy?


In [2]:
from sqlalchemy import create_engine
engine = create_engine('sqlite:////vagrant/utils/db.sqlite')

In [3]:
from sqlalchemy import Table, Column, MetaData
metadata = MetaData()
connection = engine.connect()

In [15]:
user_table = Table('user', metadata, autoload=True, autoload_with=connection)
purchase_table = Table('purchase', metadata, autoload=True, autoload_with=connection)

Let's hook this up to the ORM (rather than using Core)

We need to pull in declarative_base, build a Base class, and then map the tables we reflected.


In [5]:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

In [6]:
class User(object):
    def __init__(self, title, first_name, surname):
        self.title = title
        self.first_name = first_name
        self.surname = surname
        
    def __repr__(self):
        return "<User(id_user={}, {} {} {})>".format(self.id_user, self.title, self.first_name, self.surname)
        
class Purchase(object):
    def __init__(self, id_user, category, item, date, price):
        self.id_user = id_user
        self.category = category
        self.item = item
        self.date = date
        self.price = price
    
    def __repr__(self):
        return ("<Purchase(id_purchase={}, id_user={}, cat={}, item={}, date={}, price={})>"
                .format(self.id_purchase, self.id_user, self.category, self.item, self.date, self.price))

Now map the items together.


In [7]:
from sqlalchemy.orm import mapper, relationship, backref

In [8]:
mapper(Purchase, purchase_table)
mapper(User, user_table, properties={
        'purchases': relationship(Purchase, backref='user', order_by=purchase_table.c.id_purchase)
    })


Out[8]:
<Mapper at 0x7faa81a28eb8; User>

Let's grab a session and do some querying


In [9]:
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()

In [10]:
users = session.query(User).limit(10).all()
for u in users:
    print(u)


<User(id_user=1, Mr Arty Grant)>
<User(id_user=2, Prof Nancy Lewis)>
<User(id_user=3, Ms Paula Walsh)>
<User(id_user=4, Prof Nancy Miller)>
<User(id_user=5, Mr Matthew Gibson)>
<User(id_user=6, Mrs Sandra Rankin)>
<User(id_user=7, Ms Paula Chapman)>
<User(id_user=8, Sir John Rankin)>
<User(id_user=9, Sir John Sampson)>
<User(id_user=10, Ms Linda Smith)>

In [11]:
u1 = users[0]
print(u1.purchases)


[<Purchase(id_purchase=154, id_user=1, cat=KITCHEN, item=Garden Knife, date=2014-09-24 14:44:12.487547, price=5000)>, <Purchase(id_purchase=231, id_user=1, cat=ELECTRICAL, item=Garden Sock, date=2014-11-29 14:44:12.489055, price=6200)>, <Purchase(id_purchase=239, id_user=1, cat=HOME, item=Door Wiper, date=2014-12-26 14:44:12.489221, price=2500)>, <Purchase(id_purchase=289, id_user=1, cat=GARDEN, item=Door Wiper, date=2014-10-10 14:44:12.490888, price=9500)>, <Purchase(id_purchase=353, id_user=1, cat=HOME, item=Garden Wiper, date=2015-01-02 14:44:12.492198, price=3300)>, <Purchase(id_purchase=466, id_user=1, cat=ELECTRICAL, item=Counter Polisher, date=2015-03-31 14:44:12.494878, price=3500)>, <Purchase(id_purchase=550, id_user=1, cat=HOME, item=Door Hoover, date=2014-05-08 14:44:12.496696, price=6800)>, <Purchase(id_purchase=636, id_user=1, cat=ELECTRICAL, item=Garden Wiper, date=2014-11-25 14:44:12.498061, price=5500)>, <Purchase(id_purchase=710, id_user=1, cat=HOME, item=Garden Polisher, date=2014-08-06 14:44:12.499405, price=7700)>, <Purchase(id_purchase=792, id_user=1, cat=KITCHEN, item=Counter Wiper, date=2014-08-12 14:44:12.503900, price=7500)>, <Purchase(id_purchase=847, id_user=1, cat=HOME, item=Door Knife, date=2014-07-04 14:44:12.504976, price=1500)>, <Purchase(id_purchase=904, id_user=1, cat=KITCHEN, item=Floor Sock, date=2014-06-01 14:44:12.505871, price=3100)>, <Purchase(id_purchase=905, id_user=1, cat=GARDEN, item=Floor Polisher, date=2014-08-01 14:44:12.505886, price=6600)>, <Purchase(id_purchase=936, id_user=1, cat=HOME, item=Garden Sock, date=2014-06-28 14:44:12.506358, price=7500)>, <Purchase(id_purchase=970, id_user=1, cat=ELECTRICAL, item=Electric Knife, date=2015-02-10 14:44:12.506977, price=2300)>, <Purchase(id_purchase=997, id_user=1, cat=KITCHEN, item=Door Polisher, date=2014-12-27 14:44:12.507389, price=5800)>]

In [12]:
from sqlalchemy import func

In [13]:
results = (session.query(User, func.count(Purchase.id_purchase))
           .join(Purchase)
           .group_by(Purchase.id_user)
           .having(func.count(Purchase.id_purchase) > 10)
           .order_by(func.count(Purchase.id_purchase).desc())
           .limit(10)
           .all())
for (u, count) in results:
    print("{}, Num Purchase={}".format(u, count))


<User(id_user=67, Mr Nick Cole)>, Num Purchase=19
<User(id_user=10, Ms Linda Smith)>, Num Purchase=18
<User(id_user=1, Mr Arty Grant)>, Num Purchase=16
<User(id_user=45, Mr Nick Macintosh)>, Num Purchase=16
<User(id_user=76, Mr Arty Hartley)>, Num Purchase=16
<User(id_user=34, Mr Buzz Pink)>, Num Purchase=15
<User(id_user=49, Mrs Karen Walsh)>, Num Purchase=15
<User(id_user=98, Mrs Sandra Chapman)>, Num Purchase=15
<User(id_user=2, Prof Nancy Lewis)>, Num Purchase=14
<User(id_user=3, Ms Paula Walsh)>, Num Purchase=14

In [ ]: