Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

Some background: I am very much a novice at anything database related, my knowledge caps at creating a very basic blog with MySQL. I am currently switching from PHP/MySQL to Python and as of now I am working in Google App Engine using their NDB Datastore, but eventually will move to a hosted service running MongoDB.

I am trying to setup a simple discography cataloging data structure, with Artist, Album, and Track, so far this is what I have been trying and it doesn't work, at all.

class Track(ndb.Model):
    name = ndb.StringProperty(required=True)
    album = ndb.StringProperty(required=True)
    artists = ndb.JsonProperty(required=True)
    # ...other keys...

class Album(ndb.Model):
    name = ndb.StringProperty(required=True)
    artists = ndb.JsonProperty(required=True)
    tracks = ndb.KeyProperty(kind=Track, repeated=True)
    # ...other keys...

class Artist(ndb.Model):
    name = ndb.StringProperty(required=True)
    albums = ndb.KeyProperty(kind=Album, repeated=True)
    # ...other keys...

Now... What I originally had tried with Track, but got an error was:

class Track(ndb.Model):
    name = ndb.StringProperty(required=True)
    album = ndb.KeyProperty(kind=Album)
    artists = ndb.KeyProperty(kind=Artist, repeated=True)
    # ...other keys...

However, I get an errors like NameError: name 'Album' is not defined. Going with the album = StringProperty() and artists = JsonProperty() are making it extremely hard to search the database.

So, my question is... Looking at what I have now, I got the idea of reversing it and am wondering if it's a good idea to do so or not or find another way.

class Artist(ndb.Model):
    name = ndb.StringProperty(required=True)
    # ...other keys...

class Album(ndb.Model):
    name = ndb.StringProperty(required=True)
    artists = ndb.KeyProperty(kind=Artist, repeated=True)
    # ...other keys...

class Track(ndb.Model):
    name = ndb.StringProperty(required=True)
    album = ndb.KeyProperty(kind=Album)
    artists = ndb.KeyProperty(kind=Artist, repeated=True)
    # ...other keys...

Where Artist doesn't care about what Album it has, Album just provides the Artist.key for the artists it has. Album doesn't care about what Track it has, Track provides the Album.key for what album it is on.

So when searching I can do...

def get_album(album, artist):
    artist_key = ndb.Key(Artist, artist.lower())

    with_artist = Album.query(Album.artists == artist_key)
    return with_artist.filter(Ablum.name_lower == album.lower())

def get_tracks(album, artist):
    album_key = ndb.Key(Album, ':'.join([artist.lower(), album.lower()])

    return Track.query(Track.album == album_key)

Where Album.name_lower is a ComputedProperty(lambda self: self.name.lower()), which Artist and Track also have.

share|improve this question
add comment

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.