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\$
3
  • \$\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\$ Commented Oct 25, 2014 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\$ Commented Oct 25, 2014 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\$ Commented Oct 26, 2014 at 11:04

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.