[storm] problem with many to one relationship

James Henstridge james at jamesh.id.au
Fri Sep 18 07:06:44 BST 2009


On Fri, Sep 18, 2009 at 12:07 AM, peter websdell
<flyingdeckchair at googlemail.com> wrote:
> Hello all,
> Can anyone help me see what I'm doing wrong here?
>
> SQL
> CREATE TABLE IF NOT EXISTS `author` (
>   `id` int(8) NOT NULL auto_increment,
>   `first_name` varchar(32) NOT NULL,
>   `last_name` varchar(32) NOT NULL,
>   PRIMARY KEY  (`id`)
> ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
>
> CREATE TABLE IF NOT EXISTS `book` (
>   `id` int(8) NOT NULL auto_increment,
>   `title` varchar(64) NOT NULL,
>   `author_id` int(8) NOT NULL,
>   PRIMARY KEY  (`id`)
> ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
>
> PYTHON
> database = create_database("mysql://uname:password@localhost:3306/DB")
> store = Store(database)
> class Book(Storm):
>     __storm_table__ = "book"
>     id=Int(primary=True)
>     title = Unicode()
>     author_id=Int()
>     author = Reference(author_id,"Author.id")
>     def __init__(self, title):
>         self.title = title
>
> class Author(Storm):
>     __storm_table__="author"
>     id=Int(primary=True)
>     first_name=Unicode()
>     last_name=Unicode()
>     books= ReferenceSet(id,"Book.id")

^^^ This is the bug.  You've set up your one to many relationship
between Author's primary key and Book's primary key, rather than with
Book's foreign key pointing back to Author.  Try changing it to the
following:

    books = ReferenceSet(id, Book.author_id)

>     def __init__(self, first_name, last_name):
>         self.first_name = first_name
>         self.last_name = last_name
>
> dog=store.add(Book(u"Dog Called Demolition"))
> rankin=store.add(Author(u"Robert", u"Rankin"))
> store.flush()
> print "rankin id is %i" % (rankin.id)
> print "dog id is %i" % (dog.id)
> rankin.books.add(dog)

Due to the above bug, this statement will attempt to set dog.id to
rankin.id.  dog.author_id remains None, which is why dog.author is
also None.

> print "rankin book 1 = %s" %(rankin.books.one().title)
> print "dog author name = %s" % (dog.author.first_name)
> The error given is:
> Traceback (most recent call last):
>   File "models.py", line 33, in <module>
>     print "dog author name = %s" % (dog.author.first_name)
> AttributeError: 'NoneType' object has no attribute 'first_name'
>
> I thought storm should automatically assign the author_id to the book object
> when the book is added to the Author-object "books" set.

It should.  If it doesn't with the above bug fixed, please tell us.

James.



More information about the storm mailing list