I know this should be a elementary question, but for some reason it doesn't make sense to me. I don't understand why the line db.session.commit() isn't indented under the for statement for r in roles:? Instead it's indented under the function definition def insert_roles():, which to me doesn't make sense because nothing is happening until the for statement other than assigning the dict keys and values. I'll post the entire code and what the book says about it below. Thanks in advance for any help. . .

class Permission:
    FOLLOW = 0x01
    COMMENT = 0x02
    WRITE_ARTICLES = 0x04
    MODERATE_COMMENTS = 0x08
    ADMINISTER = 0x80


class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    default = db.Column(db.Boolean, default=False, index=True)
    permissions = db.Column(db.Integer)
    users = db.relationship('User', backref='role', lazy='dynamic')

    @staticmethod
    def insert_roles():
        roles = {
            'User': (Permission.FOLLOW |
                     Permission.COMMENT |
                     Permission.WRITE_ARTICLES, True),
            'Moderator': (Permission.FOLLOW |
                          Permission.COMMENT |
                          Permission.WRITE_ARTICLES |
                          Permission.MODERATE_COMMENTS, False),
            'Administrator': (0xff, False)
        }
        for r in roles:
            role = Role.query.filter_by(name=r).first()
            if role is None:
                role = Role(name=r)
            role.permissions = roles[r][0]
            role.default = roles[r][1]
            db.session.add(role)
        db.session.commit()

    def __repr__(self):
        return '<Role %r>' % self.name

From the book:

The insert_roles() function does not directly create new role objects. Instead, it tries to find existing roles by name and update those. A new role object is created only for role names that aren’t in the database already. This is done so that the role list can be updated in the future when changes need to be made. To add a new role or change the permission assignments for a role, change the roles array and rerun the function. Note that the “Anonymous” role does not need to be represented in the database, as it is designed to represent users who are not in the database.

share|improve this question
up vote 0 down vote accepted

The reason db.session.commit() is outdented is that it needs to run after the loop has finished doing its thing - adding each role to the db session. This is the command that essentially "permanently writes" the info into the database - the add() function stores the data in temporary memory, but commit() actually commits it to disk. Writing to memory is a fairly cheap operation, committing to disk is more expensive, so you would want to save that step until the end. Does that make sense?

share|improve this answer
    
Thanks so much for your help. . .Yes, it makes perfect sense. I assume this is standard operating procedure for committing values to a .db, Calling Commit AFTER any loops? Also, I'm assuming it still would've worked had it NOT been out-dented? Or would this cause it not to work somehow? – Chris Kavanagh Jul 27 '14 at 7:53
    
It all depends on how you want to handle the transaction. By calling commit after the loop, either all of the roles will be inserted/updated or none of them will. Had commit been called inside the loop, each role would have ended up in its own transaction and been inserted/updated independently of the others. – dirn Jul 27 '14 at 12:34
    
@ChrisKavanagh adding on to dirn's comment, it all depends on the number of transactions you want to have, vs. the safety you want to have. Committing after each role addition is safest, as there's always the possibility the DB connection will be broken somehow or one or the other server will die. However, if you're talking about a very high-volume server that will be processing thousands/millions of transactions, it makes more sense to try and group your DB operations together. – MattDMo Jul 27 '14 at 14:42
    
I got it. Thank you both for your help, it's greatly appreciated! – Chris Kavanagh Jul 28 '14 at 21:13

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.