I'm not sure if this is a bug or I am just setting up the attribute
wrong. Anyways, I'm having a problem defining count-type SQL mapped
attribute in a situation with many-to-many relationships.

The example here uses the classic book-author many-to-many relation.
An author can have many books, and a book can be by more than one
author.

Again, the code is a self-contained test case.

<code>

from sqlalchemy import create_engine, Table, Column, Integer, String,
MetaData, ForeignKey
from sqlalchemy.orm import mapper, relation, backref, column_property,
sessionmaker
from sqlalchemy.sql import select, func

DB_URI='postgres://postg...@localhost/postgres' #Replace this
accordingly
db_engine=create_engine(DB_URI, echo=True)
metadata = MetaData()

books=Table('books', metadata,
              Column('id', Integer, primary_key=True),
              Column('title', String(100), nullable=False)
              )
class Book(object):
    def __init__(self, title):
        self.title=title

authors=Table('authors', metadata,
              Column('id', Integer, primary_key=True),
              Column('name', String(100))
              )

class Author(object):
    def __init__(self, name):
        self.name=name

book_authors=Table('book_authors', metadata,
                Column('book_id', Integer, ForeignKey('books.id'),
primary_key=True),
                Column('author_id', Integer, ForeignKey('authors.id'),
primary_key=True)
                )

mapper(Book, books)
mapper(Author, authors, properties={
    'books': relation(Book, secondary=book_authors,
backref='authors'),
    'book_count': column_property(select([func.count(books.c.id)],
book_authors.c.author_id==books.c.id).label('books_count'))
    })

if __name__ == '__main__':
    metadata.create_all(db_engine)
    s=sessionmaker(bind=db_engine)()
    b1=Book('I, Robot')
    b2=Book('Foundation')
    b3=Book('Rendezvous with Rama')
    a1=Author('Isaac Asimov')
    a2=Author('Arthur C. Clarke')
    a1.books=[b1, b2]
    a2.books=[b3]
    s.add_all([b1, b2, b3, a1, a2])
    s.commit()
    try:
        #Isaac Asimov has two books
        assert len(a1.books)==2
        #But reading book_count would return the total number of books
in books table (in this case 3)
        assert a1.book_count==2 #Fails
    finally:
        s.close()
        metadata.drop_all(db_engine)

</code>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to