tags:

views:

42

answers:

1

In SQLAlchemy, we can declare tables and their relations like this:

user = Table(
    'users', metadata,
    Column('id', Integer, primary_key=True))

address = Table(
    'adresses', metadata,
    Column('id', Integer, primary_key=True),
    Column('user_id', Integer, ForeignKey('user.id')))

class User(object): pass

class Address(object): pass

session.mapper(User, user, properties=dict(
    'address' = relation(Address, backref='user', cascade="all")))

(Please notice the cascade relation in the line above.)

However, we can also use an alternate shorthand style, called declarative style, in which we can express the same things in fewer lines of code, omitting the mapper() relationships:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)

class Adress(Base):
    __tablename__ = 'adresses'
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('user.id')))

But if we use this declarative style, is there an alternative way to define cascade relationships?

+2  A: 

Actually the use of "declarative" does not mean you omit the relationships. You still specify them, roughly the same way, but directly on the class as attributes rather than in the mapper:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    address = relation('Address', backref='user', cascade='all')

class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('users.id'))

(Note that I've fixed the spelling of "address", in case you cut-and-paste this.)

The declarative documentation covers this. Note that in the simple cases, it figures out what foreign keys to use automatically, but you can be more explicit if required.

Also note the use of the string 'Address' since at the time I use it in the User class the related class has not yet been defined.

Peter Hansen