2
\$\begingroup\$

I'm working on a project with Flask and I'm trying to follow Miguel Grinberg's Flask tutorial as closely as possible while creating what I need for my own project.

Overall, how does it look? Miguel's models were relatively simple and since mine are so complicated, I'm not sure if I'm doing it correctly. I tried to normalize the db as much as I could, but databases are really new to me.

## Relationships
manga_to_author = db.Table('manga_to_author',
    db.Column('author_id', db.Integer, db.ForeignKey('author.id')),
    db.Column('manga_id', db.Integer, db.ForeignKey('manga.id'))
)

manga_to_artist = db.Table('manga_to_artist',
    db.Column('artist_id', db.Integer, db.ForeignKey('artist.id')),
    db.Column('manga_id', db.Integer, db.ForeignKey('manga.id'))
)

manga_to_scanlator = db.Table('manga_to_scanlator',
    db.Column('scanlator_id', db.Integer, db.ForeignKey('scanlator.id')),
    db.Column('manga_id', db.Integer, db.ForeignKey('manga.id'))
)

manga_to_publisher = db.Table('manga_to_publisher',
    db.Column('publisher_id', db.Integer, db.ForeignKey('publisher.id')),
    db.Column('manga_id', db.Integer, db.ForeignKey('manga.id'))
)

manga_to_genre = db.Table('manga_to_genre',
    db.Column('genre_id', db.Integer, db.ForeignKey('genre.id')),
    db.Column('manga_id', db.Integer, db.ForeignKey('manga.id'))
)

manga_to_tag = db.Table('manga_to_tag',
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
    db.Column('manga_id', db.Integer, db.ForeignKey('manga.id'))
)

manga_to_content_warning = db.Table('manga_to_content_warning',
    db.Column('content_warning_id', db.Integer, db.ForeignKey('content_warning.id')),
    db.Column('manga_id', db.Integer, db.ForeignKey('manga.id'))
)

## Tables
class Manga(db.Model):
    __tablename__ = 'manga'

    id = db.Column(db.Integer, primary_key=True)
    date_added = db.Column() # ===> DATETIME????
    date_modified = db.Column() # ===> DATETIME????
    gtin = db.Column(db.Integer) # OR db.String(20)

    series_id = db.Column(db.Integer, db.ForeignKey('series.id'))
    series = db.relationship('Series', backref=db.backref('manga', lazy='dynamic'))

    series_relation_id = db.Column(db.Integer, db.ForeignKey('series_relation.id'))
    series_relation = db.relationship('SeriesRelation', backref=db.backref('manga', lazy='dynamic'))

    title = db.Column(db.String())
    original_title = db.Column(db.String())
    romaji_title = db.Column(db.String())
    english_title = db.Column(db.String())

    book_language_id = db.Column(db.Integer, db.ForeignKey('language.id'))
    book_language = db.relationship('Language', backref=db.backref('manga', lazy='dynamic'))

    book_type_id = db.Column(db.Integer, db.ForeignKey('book_type.id'))
    book_type = db.relationship('BookType', backref=db.backref('manga', lazy='dynamic'))

    series_type_id = db.Column(db.Integer, db.ForeignKey('series_type.id'))
    series_type = db.relationship('SeriesType', backref=db.backref('manga', lazy='dynamic'))

    storage_type_id = db.Column(db.Integer, db.ForeignKey('storage_type.id'))
    storage_type = db.relationship('StorageType', backref=db.backref('manga', lazy='dynamic'))

    collection_status_id = db.Column(db.Integer, db.ForeignKey('collection_status.id'))
    collection_status = db.relationship('CollectionStatus', backref=db.backref('manga', lazy='dynamic'))

    publication_status_id = db.Column(db.Integer, db.ForeignKey('publication_status.id'))
    publication_status = db.relationship('PublicationStatus', backref=db.backref('manga', lazy='dynamic'))


    maximum_volume = db.Column(db.Integer)
    volume_list = db.Column(db.String())
    chapter_count = db.Column(db.Integer)
    page_count = db.Column(db.Integer)

    manga_to_author = db.relationship('Author', secondary=manga_to_author,
        backref=db.backref('manga', lazy='dynamic'))

    manga_to_artist = db.relationship('Artist', secondary=manga_to_artist,
        backref=db.backref('manga', lazy='dynamic'))

    manga_to_scanlator = db.relationship('Scanlator', secondary=manga_to_scanlator,
        backref=db.backref('manga', lazy='dynamic'))

    manga_to_publisher = db.relationship('Publisher', secondary=manga_to_publisher,
        backref=db.backref('manga', lazy='dynamic'))

    date_published = db.Column(db.String()) # ===> DATE????

    serialized_in_id = db.Column(db.Integer, db.ForeignKey('serialized_in.id'))
    serialized_in = db.relationship('SerializedIn', backref=db.backref('manga', lazy='dynamic'))

    demography_id = db.Column(db.Integer, db.ForeignKey('demography.id'))
    demography = db.relationship('Demography', backref=db.backref('manga', lazy='dynamic'))

    content_rating_id = db.Column(db.Integer, db.ForeignKey('content_rating.id'))
    content_rating = db.relationship('ContentRating', backref=db.backref('manga', lazy='dynamic'))

    love_score = db.Column(db.Float)

    manga_to_genre = db.relationship('Genre', secondary=manga_to_genre,
        backref=db.backref('manga', lazy='dynamic'))

    manga_to_tag = db.relationship('Tag', secondary=manga_to_tag,
        backref=db.backref('manga', lazy='dynamic'))

    manga_to_content_warning = db.relationship('ContentWarning', secondary=manga_to_content_warning,
        backref=db.backref('manga', lazy='dynamic'))


    summary = db.Column(db.Text)
    extra_notes = db.Column(db.Text)

    cover_id = db.Column(db.Integer, db.ForeignKey('cover.id'))
    cover = db.relationship('Cover', backref=db.backref('manga', lazy='dynamic'))

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Manga (title='%s')>" % (self.title)



class Series(db.Model):
    __tablename__: 'series'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Series (name='%s')>" % self.name


class SeriesRelation(db.Model):
    __tablename__: 'series_relation'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<SeriesRelation (name='%s')>" % self.name


class BookLanguage(db.Model):
    __tablename__: 'book_language'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    book_language_code = db.Column(db.String(3))

    def __init__(self, name, book_language_code):
        self.name = name
        self.book_language_code = book_language_code

    def __repr__(self):
        return "<BookLanguage (name='%s')>" % self.name


class BookType(db.Model):
    __tablename__: 'book_type'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<BookType (name='%s')>" % self.name


class SeriesType(db.Model):
    __tablename__: 'series_type'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<SeriesType (name='%s')>" % self.name

class StorageType(db.Model):
    __tablename__: 'storage_type'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<StorageType (name='%s')>" % self.name


class CollectionStatus(db.Model):
    __tablename__: 'collection_status'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    booli = db.Column(db.Boolean) #????

    def __init__(self, name, booli):
        self.name = name
        self.booli = booli

    def __repr__(self):
        return "<CollectionStatus (name='%s')>" % self.name


class PublicationStatus(db.Model):
    __tablename__: 'publication_status'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    booli = db.Column(db.Boolean) #????

    def __init__(self, name, booli):
        self.name = name
        self.booli = booli

    def __repr__(self):
        return "<PublicationStatus (name='%s')>" % self.name


class Author(db.Model):
    __tablename__: 'author'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Author (name='%s')>" % self.name


class Artist(db.Model):
    __tablename__: 'artist'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Artist (name='%s')>" % self.name


class Scanlator(db.Model):
    __tablename__: 'scanlator'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Scanlator (name='%s')>" % self.name


class Publisher(db.Model):
    __tablename__: 'publisher'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Publisher (name='%s')>" % self.name


class SerializedIn(db.Model):
    __tablename__: 'serialized_in'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<SerializedIn (name='%s')>" % self.name


class Demography(db.Model):
    __tablename__: 'demography'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Demography (name='%s')>" % self.name


class ContentRating(db.Model):
    __tablename__: 'content_rating'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<ContentRating (name='%s')>" % self.name


class Genre(db.Model):
    __tablename__: 'genre'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Genre (name='%s')>" % self.name


class Tag(db.Model):
    __tablename__: 'tag'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Tag (name='%s')>" % self.name


class ContentWarning(db.Model):
    __tablename__: 'content_warning'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<ContentWarning (name='%s')>" % self.name


class Cover(db.Model):
    __tablename__: 'cover'

    id = db.Column(db.Integer, primary_key=True)
    date_added = db.Column() # ===> DATETIME????
    date_modified = db.Column() # ===> DATETIME????
    name = db.Column(db.String()) # no idea
    filename = db.Column(db.String()) # no idea; filename of image with extension
    filesize = db.Column(db.Integer) # filesize

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Cover (name='%s')>" % self.name
\$\endgroup\$
  • \$\begingroup\$ Looks good to me. It may look complicated because you have many objects. But you really need those objects, so this is inevitable. \$\endgroup\$ – Stop ongoing harm to Monica Oct 25 '14 at 22:04
  • \$\begingroup\$ I agree, looks ok to me. One thing I usually do is to extract common functions like __repr__ into a common base class (like ModelMixin) and then define it in a generic way: return "<%s (name='%s')>" % (self.__class__.__name__, getattr(self, 'name', 'NO NAME')). Since you only ever seem to be using name in __repr__ that would work well for you. \$\endgroup\$ – Lukas Graf Oct 25 '14 at 22:27
  • \$\begingroup\$ I see. That does seem to be more efficient. Pardon my ignorance, but where would I put it and how would I call it for use? \$\endgroup\$ – user2986242 Oct 26 '14 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.