import sqlite3
db = sqlite3.connect('cheese_emporium.db')
db.execute('CREATE TABLE cheese(id INTEGER, name TEXT)')
db.executemany(
    'INSERT INTO cheese VALUES (?, ?)',
    [(1, 'red leicester'),
     (2, 'wensleydale'),
     (3, 'cheddar'),
    ]
)
db.commit()
db.close()
---

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Date, Integer, String, Table, ForeignKey
from sqlalchemy.orm import relationship

Base = declarative_base()  

class Customer(Base):  
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    def __repr__(self):
        return "<Customer(name='%s')>" % (self.name)

purchases_cheeses = Table(  
    'purchases_cheeses', Base.metadata,
    Column('purch_id', Integer, ForeignKey('purchases.id', primary_key=True)),
    Column('cheese_id', Integer, ForeignKey('cheeses.id', primary_key=True))
) 

class Cheese(Base):  
    __tablename__ = 'cheeses'
    id = Column(Integer, primary_key=True)
    kind = Column(String, nullable=False)
    purchases = relationship(  
        'Purchase', secondary='purchases_cheeses', back_populates='cheeses'  
    )
    def __repr__(self):
        return "<Cheese(kind='%s')>" % (self.kind)

class Purchase(Base):
    __tablename__ = 'purchases'
    id = Column(Integer, primary_key=True)
    customer_id = Column(Integer, ForeignKey('customers.id', primary_key=True))
    purchase_date = Column(Date, nullable=False)
    customer = relationship('Customer')
    cheeses = relationship(  
        'Cheese', secondary='purchases_cheeses', back_populates='purchases'
    )
    def __repr__(self):
       return ("<Purchase(customer='%s', dt='%s')>" %
                (self.customer.name, self.purchase_date))
---

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sess = Session()
leicester = Cheese(kind='Red Leicester')
camembert = Cheese(kind='Camembert')
sess.add_all((camembert, leicester))
cat = Customer(name='Cat')
sess.add(cat)
sess.commit()  

import datetime
d = datetime.date(1971, 12, 18)
p = Purchase(purchase_date=d, customer=cat)
p.cheeses.append(camembert)   
sess.add(p)
sess.commit()
---

leicester = Cheese.objects.create(type='Red Leicester')
camembert = Cheese.objects.create(type='Camembert')
leicester.save()  
camembert.save()

doug = Customer.objects.create(name='Douglas')
doug.save()

# Dodaj czas zakupu
import datetime
now = datetime.datetime(1971, 12, 18, 20)
day = datetime.timedelta(1)

p = Purchase(purchase_date=now - 1 * day, customer=doug)
p.save()
p.cheeses.add(camembert, leicester)  
---

leicester = Cheese.create(kind='Red Leicester')
camembert = Cheese.create(kind='Camembert')
cat = Customer.create(name='Cat')

import datetime
d = datetime.date(1971, 12, 18)

p = Purchase.create(purchase_date=d, customer=cat)  
PurchaseCheese.create(purchase=p, cheese=camembert)  
PurchaseCheese.create(purchase=p, cheese=leicester)
---

import datetime
from pony import orm
db = orm.Database()
db.bind('sqlite', ':memory:')
class Cheese(db.Entity):  
    type = orm.Required(str)  
    purchases = orm.Set(lambda: Purchase)  
class Customer(db.Entity):
    name = orm.Required(str)
    purchases = orm.Set(lambda: Purchase)  
class Purchase(db.Entity):
    date = orm.Required(datetime.date)
    customer = orm.Required(Customer)  
    cheeses = orm.Set(Cheese)  
db.generate_mapping(create_tables=True)
---

camembert = Cheese(type='Camembert')
leicester = Cheese(type='Red Leicester')
cat = Customer(name='Cat')
doug = Customer(name='Douglas')

d = datetime.date(1971, 12, 18)
day = datetime.timedelta(1)
Purchase(date=(d - 1 * day), customer=doug, cheeses={camembert, leicester})
Purchase(date=d, customer=cat, cheeses={camembert})
orm.commit()
---

yesterday = d - 1.1 * day
for cheese in (
        orm.select(p.cheeses for p in Purchase if p.date > yesterday)  
    ):
    print(cheese.type)
for cheese, purchase_count in (
        orm.left_join((c, orm.count(p))  
        for c in Cheese
        for p in c.purchases)
    ):
    print(cheese.type, purchase_count)
---

