mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-22 08:32:09 -04:00
546015e6e1
to allow ad-hoc display of the source of any file, as well as a "directory listing" structure. - reorganize examples/ to take advantage of new extension. in particular, keep moving all the descriptive text for files etc. into module docstrings, taking more advantage of self-documentation.
99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
"""basic_association.py
|
|
|
|
illustrate a many-to-many relationship between an
|
|
"Order" and a collection of "Item" objects, associating a purchase price
|
|
with each via an association object called "OrderItem"
|
|
|
|
The association object pattern is a form of many-to-many which
|
|
associates additional data with each association between parent/child.
|
|
|
|
The example illustrates an "order", referencing a collection
|
|
of "items", with a particular price paid associated with each "item".
|
|
|
|
"""
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import (create_engine, MetaData, Table, Column, Integer,
|
|
String, DateTime, Float, ForeignKey, and_)
|
|
from sqlalchemy.orm import mapper, relationship, Session
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
|
|
Base = declarative_base()
|
|
|
|
class Order(Base):
|
|
__tablename__ = 'order'
|
|
|
|
order_id = Column(Integer, primary_key=True)
|
|
customer_name = Column(String(30), nullable=False)
|
|
order_date = Column(DateTime, nullable=False, default=datetime.now())
|
|
order_items = relationship("OrderItem", cascade="all, delete-orphan",
|
|
backref='order')
|
|
|
|
def __init__(self, customer_name):
|
|
self.customer_name = customer_name
|
|
|
|
class Item(Base):
|
|
__tablename__ = 'item'
|
|
item_id = Column(Integer, primary_key=True)
|
|
description = Column(String(30), nullable=False)
|
|
price = Column(Float, nullable=False)
|
|
|
|
def __init__(self, description, price):
|
|
self.description = description
|
|
self.price = price
|
|
|
|
def __repr__(self):
|
|
return 'Item(%r, %r)' % (
|
|
self.description, self.price
|
|
)
|
|
|
|
class OrderItem(Base):
|
|
__tablename__ = 'orderitem'
|
|
order_id = Column(Integer, ForeignKey('order.order_id'), primary_key=True)
|
|
item_id = Column(Integer, ForeignKey('item.item_id'), primary_key=True)
|
|
price = Column(Float, nullable=False)
|
|
|
|
def __init__(self, item, price=None):
|
|
self.item = item
|
|
self.price = price or item.price
|
|
item = relationship(Item, lazy='joined')
|
|
|
|
if __name__ == '__main__':
|
|
engine = create_engine('sqlite://')
|
|
Base.metadata.create_all(engine)
|
|
|
|
session = Session(engine)
|
|
|
|
# create catalog
|
|
tshirt, mug, hat, crowbar = (
|
|
Item('SA T-Shirt', 10.99),
|
|
Item('SA Mug', 6.50),
|
|
Item('SA Hat', 8.99),
|
|
Item('MySQL Crowbar', 16.99)
|
|
)
|
|
session.add_all([tshirt, mug, hat, crowbar])
|
|
session.commit()
|
|
|
|
# create an order
|
|
order = Order('john smith')
|
|
|
|
# add three OrderItem associations to the Order and save
|
|
order.order_items.append(OrderItem(mug))
|
|
order.order_items.append(OrderItem(crowbar, 10.99))
|
|
order.order_items.append(OrderItem(hat))
|
|
session.add(order)
|
|
session.commit()
|
|
|
|
# query the order, print items
|
|
order = session.query(Order).filter_by(customer_name='john smith').one()
|
|
print([(order_item.item.description, order_item.price)
|
|
for order_item in order.order_items])
|
|
|
|
# print customers who bought 'MySQL Crowbar' on sale
|
|
q = session.query(Order).join('order_items', 'item')
|
|
q = q.filter(and_(Item.description == 'MySQL Crowbar',
|
|
Item.price > OrderItem.price))
|
|
|
|
print([order.customer_name for order in q])
|