Browse Source

Be more explicit about nullable columns

Peter Justin 8 years ago
parent
commit
ad3090d61f

+ 60 - 57
flaskbb/forum/models.py

@@ -34,27 +34,18 @@ topictracker = db.Table(
     db.Column('user_id', db.Integer(), db.ForeignKey('users.id'),
     db.Column('user_id', db.Integer(), db.ForeignKey('users.id'),
               nullable=False),
               nullable=False),
     db.Column('topic_id', db.Integer(),
     db.Column('topic_id', db.Integer(),
-              db.ForeignKey('topics.id',
-                            use_alter=True, name="fk_tracker_topic_id"),
+              db.ForeignKey('topics.id', use_alter=True,
+                            name="fk_tracker_topic_id"),
               nullable=False))
               nullable=False))
 
 
 
 
-# m2m table for group-forum permission mapping
 forumgroups = db.Table(
 forumgroups = db.Table(
     'forumgroups',
     'forumgroups',
-    db.Column(
-        'group_id',
-        db.Integer(),
-        db.ForeignKey('groups.id'),
-        nullable=False
-    ),
-    db.Column(
-        'forum_id',
-        db.Integer(),
-        db.ForeignKey('forums.id', use_alter=True, name="fk_forum_id"),
-        nullable=False
-    )
-)
+    db.Column('group_id', db.Integer(), db.ForeignKey('groups.id'),
+              nullable=False),
+    db.Column('forum_id', db.Integer(),
+              db.ForeignKey('forums.id', use_alter=True, name="fk_forum_id"),
+              nullable=False))
 
 
 
 
 class TopicsRead(db.Model, CRUDMixin):
 class TopicsRead(db.Model, CRUDMixin):
@@ -70,7 +61,8 @@ class TopicsRead(db.Model, CRUDMixin):
                          db.ForeignKey("forums.id", use_alter=True,
                          db.ForeignKey("forums.id", use_alter=True,
                                        name="fk_tr_forum_id"),
                                        name="fk_tr_forum_id"),
                          primary_key=True)
                          primary_key=True)
-    last_read = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
+    last_read = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                          nullable=False)
 
 
 
 
 class ForumsRead(db.Model, CRUDMixin):
 class ForumsRead(db.Model, CRUDMixin):
@@ -82,21 +74,27 @@ class ForumsRead(db.Model, CRUDMixin):
                          db.ForeignKey("forums.id", use_alter=True,
                          db.ForeignKey("forums.id", use_alter=True,
                                        name="fk_fr_forum_id"),
                                        name="fk_fr_forum_id"),
                          primary_key=True)
                          primary_key=True)
-    last_read = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    cleared = db.Column(UTCDateTime(timezone=True))
+    last_read = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                          nullable=False)
+    cleared = db.Column(UTCDateTime(timezone=True), nullable=True)
 
 
 
 
 class Report(db.Model, CRUDMixin):
 class Report(db.Model, CRUDMixin):
     __tablename__ = "reports"
     __tablename__ = "reports"
 
 
+    # TODO: Store in addition to the info below topic title and username
+    # as well. So that in case a user or post gets deleted, we can
+    # still view the report
+
     id = db.Column(db.Integer, primary_key=True)
     id = db.Column(db.Integer, primary_key=True)
     reporter_id = db.Column(db.Integer, db.ForeignKey("users.id"),
     reporter_id = db.Column(db.Integer, db.ForeignKey("users.id"),
-                            nullable=False)
-    reported = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    post_id = db.Column(db.Integer, db.ForeignKey("posts.id"), nullable=False)
-    zapped = db.Column(UTCDateTime(timezone=True))
-    zapped_by = db.Column(db.Integer, db.ForeignKey("users.id"))
-    reason = db.Column(db.Text)
+                            nullable=True)
+    reported = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                         nullable=False)
+    post_id = db.Column(db.Integer, db.ForeignKey("posts.id"), nullable=True)
+    zapped = db.Column(UTCDateTime(timezone=True), nullable=True)
+    zapped_by = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=True)
+    reason = db.Column(db.Text, nullable=True)
 
 
     post = db.relationship(
     post = db.relationship(
         "Post", lazy="joined",
         "Post", lazy="joined",
@@ -140,13 +138,15 @@ class Post(db.Model, CRUDMixin):
                          db.ForeignKey("topics.id",
                          db.ForeignKey("topics.id",
                                        use_alter=True,
                                        use_alter=True,
                                        name="fk_post_topic_id",
                                        name="fk_post_topic_id",
-                                       ondelete="CASCADE"))
+                                       ondelete="CASCADE"),
+                         nullable=True)
     user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=True)
     user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=True)
     username = db.Column(db.String(200), nullable=False)
     username = db.Column(db.String(200), nullable=False)
     content = db.Column(db.Text, nullable=False)
     content = db.Column(db.Text, nullable=False)
-    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    date_modified = db.Column(UTCDateTime(timezone=True))
-    modified_by = db.Column(db.String(200))
+    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                             nullable=False)
+    date_modified = db.Column(UTCDateTime(timezone=True), nullable=True)
+    modified_by = db.Column(db.String(200), nullable=True)
 
 
     # Properties
     # Properties
     @property
     @property
@@ -287,23 +287,27 @@ class Topic(db.Model, CRUDMixin):
                                        name="fk_topic_forum_id"),
                                        name="fk_topic_forum_id"),
                          nullable=False)
                          nullable=False)
     title = db.Column(db.String(255), nullable=False)
     title = db.Column(db.String(255), nullable=False)
-    user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
+    user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=True)
     username = db.Column(db.String(200), nullable=False)
     username = db.Column(db.String(200), nullable=False)
-    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    last_updated = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    locked = db.Column(db.Boolean, default=False)
-    important = db.Column(db.Boolean, default=False)
-    views = db.Column(db.Integer, default=0)
-    post_count = db.Column(db.Integer, default=0)
+    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                             nullable=False)
+    last_updated = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                             nullable=False)
+    locked = db.Column(db.Boolean, default=False, nullable=False)
+    important = db.Column(db.Boolean, default=False, nullable=False)
+    views = db.Column(db.Integer, default=0, nullable=False)
+    post_count = db.Column(db.Integer, default=0, nullable=False)
 
 
     # One-to-one (uselist=False) relationship between first_post and topic
     # One-to-one (uselist=False) relationship between first_post and topic
-    first_post_id = db.Column(db.Integer, db.ForeignKey("posts.id",
-                                                        ondelete="CASCADE"))
+    first_post_id = db.Column(db.Integer,
+                              db.ForeignKey("posts.id", ondelete="CASCADE"),
+                              nullable=True)
     first_post = db.relationship("Post", backref="first_post", uselist=False,
     first_post = db.relationship("Post", backref="first_post", uselist=False,
                                  foreign_keys=[first_post_id])
                                  foreign_keys=[first_post_id])
 
 
     # One-to-one
     # One-to-one
-    last_post_id = db.Column(db.Integer, db.ForeignKey("posts.id"))
+    last_post_id = db.Column(db.Integer, db.ForeignKey("posts.id"),
+                             nullable=True)
 
 
     last_post = db.relationship("Post", backref="last_post", uselist=False,
     last_post = db.relationship("Post", backref="last_post", uselist=False,
                                 foreign_keys=[last_post_id])
                                 foreign_keys=[last_post_id])
@@ -330,20 +334,17 @@ class Topic(db.Model, CRUDMixin):
         return url_for("forum.view_topic", topic_id=self.id, slug=self.slug)
         return url_for("forum.view_topic", topic_id=self.id, slug=self.slug)
 
 
     def first_unread(self, topicsread, user, forumsread=None):
     def first_unread(self, topicsread, user, forumsread=None):
-        """Returns the url to the first unread post if any else to the topic
-        itself.
+        """Returns the url to the first unread post. If no unread posts exist
+        it will return the url to the topic.
 
 
         :param topicsread: The topicsread object for the topic
         :param topicsread: The topicsread object for the topic
-
         :param user: The user who should be checked if he has read the
         :param user: The user who should be checked if he has read the
                      last post in the topic
                      last post in the topic
-
         :param forumsread: The forumsread object in which the topic is. If you
         :param forumsread: The forumsread object in which the topic is. If you
                         also want to check if the user has marked the forum as
                         also want to check if the user has marked the forum as
                         read, than you will also need to pass an forumsread
                         read, than you will also need to pass an forumsread
                         object.
                         object.
         """
         """
-
         # If the topic is unread try to get the first unread post
         # If the topic is unread try to get the first unread post
         if topic_is_unread(self, topicsread, user, forumsread):
         if topic_is_unread(self, topicsread, user, forumsread):
             query = Post.query.filter(Post.topic_id == self.id)
             query = Post.query.filter(Post.topic_id == self.id)
@@ -526,8 +527,7 @@ class Topic(db.Model, CRUDMixin):
         self.username = user.username
         self.username = user.username
 
 
         # Set the last_updated time. Needed for the readstracker
         # Set the last_updated time. Needed for the readstracker
-        created = time_utcnow()
-        self.date_created = self.last_updated = created
+        self.date_created = self.last_updated = time_utcnow()
 
 
         # Insert and commit the topic
         # Insert and commit the topic
         db.session.add(self)
         db.session.add(self)
@@ -536,8 +536,8 @@ class Topic(db.Model, CRUDMixin):
         # Create the topic post
         # Create the topic post
         post.save(user, self)
         post.save(user, self)
 
 
-        # Update the first post id
-        self.first_post_id = post.id
+        # Update the first and last post id
+        self.last_post_id = self.first_post_id = post.id
 
 
         # Update the topic count
         # Update the topic count
         forum.topic_count += 1
         forum.topic_count += 1
@@ -611,26 +611,29 @@ class Forum(db.Model, CRUDMixin):
     category_id = db.Column(db.Integer, db.ForeignKey("categories.id"),
     category_id = db.Column(db.Integer, db.ForeignKey("categories.id"),
                             nullable=False)
                             nullable=False)
     title = db.Column(db.String(255), nullable=False)
     title = db.Column(db.String(255), nullable=False)
-    description = db.Column(db.Text)
+    description = db.Column(db.Text, nullable=True)
     position = db.Column(db.Integer, default=1, nullable=False)
     position = db.Column(db.Integer, default=1, nullable=False)
     locked = db.Column(db.Boolean, default=False, nullable=False)
     locked = db.Column(db.Boolean, default=False, nullable=False)
     show_moderators = db.Column(db.Boolean, default=False, nullable=False)
     show_moderators = db.Column(db.Boolean, default=False, nullable=False)
-    external = db.Column(db.String(200))
+    external = db.Column(db.String(200), nullable=True)
 
 
     post_count = db.Column(db.Integer, default=0, nullable=False)
     post_count = db.Column(db.Integer, default=0, nullable=False)
     topic_count = db.Column(db.Integer, default=0, nullable=False)
     topic_count = db.Column(db.Integer, default=0, nullable=False)
 
 
     # One-to-one
     # One-to-one
-    last_post_id = db.Column(db.Integer, db.ForeignKey("posts.id"))
+    last_post_id = db.Column(db.Integer, db.ForeignKey("posts.id"),
+                             nullable=True)
     last_post = db.relationship("Post", backref="last_post_forum",
     last_post = db.relationship("Post", backref="last_post_forum",
                                 uselist=False, foreign_keys=[last_post_id])
                                 uselist=False, foreign_keys=[last_post_id])
 
 
-    # Not nice, but needed to improve the performance
-    last_post_title = db.Column(db.String(255))
-    last_post_user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
-    last_post_username = db.Column(db.String(255))
+    # Not nice, but needed to improve the performance; can be set to NULL
+    # if the forum has no posts
+    last_post_title = db.Column(db.String(255), nullable=True)
+    last_post_user_id = db.Column(db.Integer, db.ForeignKey("users.id"),
+                                  nullable=True)
+    last_post_username = db.Column(db.String(255), nullable=True)
     last_post_created = db.Column(UTCDateTime(timezone=True),
     last_post_created = db.Column(UTCDateTime(timezone=True),
-                                  default=time_utcnow)
+                                  default=time_utcnow, nullable=True)
 
 
     # One-to-many
     # One-to-many
     topics = db.relationship(
     topics = db.relationship(
@@ -912,7 +915,7 @@ class Category(db.Model, CRUDMixin):
 
 
     id = db.Column(db.Integer, primary_key=True)
     id = db.Column(db.Integer, primary_key=True)
     title = db.Column(db.String(255), nullable=False)
     title = db.Column(db.String(255), nullable=False)
-    description = db.Column(db.Text)
+    description = db.Column(db.Text, nullable=True)
     position = db.Column(db.Integer, default=1, nullable=False)
     position = db.Column(db.Integer, default=1, nullable=False)
 
 
     # One-to-many
     # One-to-many

+ 12 - 8
flaskbb/message/models.py

@@ -20,14 +20,17 @@ class Conversation(db.Model, CRUDMixin):
 
 
     id = db.Column(db.Integer, primary_key=True)
     id = db.Column(db.Integer, primary_key=True)
     user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
     user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
-    from_user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
-    to_user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
+    from_user_id = db.Column(db.Integer, db.ForeignKey("users.id"),
+                             nullable=True)
+    to_user_id = db.Column(db.Integer, db.ForeignKey("users.id"),
+                           nullable=True)
     shared_id = db.Column(UUIDType, nullable=False)
     shared_id = db.Column(UUIDType, nullable=False)
-    subject = db.Column(db.String(255))
-    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    trash = db.Column(db.Boolean, nullable=False, default=False)
-    draft = db.Column(db.Boolean, nullable=False, default=False)
-    unread = db.Column(db.Boolean, nullable=False, default=True)
+    subject = db.Column(db.String(255), nullable=True)
+    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                             nullable=False)
+    trash = db.Column(db.Boolean, default=False, nullable=False)
+    draft = db.Column(db.Boolean, default=False, nullable=False)
+    unread = db.Column(db.Boolean, default=False, nullable=False)
 
 
     messages = db.relationship(
     messages = db.relationship(
         "Message", lazy="joined", backref="conversation",
         "Message", lazy="joined", backref="conversation",
@@ -85,7 +88,8 @@ class Message(db.Model, CRUDMixin):
     # the user who wrote the message
     # the user who wrote the message
     user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
     user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
     message = db.Column(db.Text, nullable=False)
     message = db.Column(db.Text, nullable=False)
-    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
+    date_created = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                             nullable=False)
 
 
     user = db.relationship("User", lazy="joined")
     user = db.relationship("User", lazy="joined")
 
 

+ 24 - 19
flaskbb/user/models.py

@@ -24,8 +24,11 @@ from flaskbb.message.models import Conversation
 
 
 groups_users = db.Table(
 groups_users = db.Table(
     'groups_users',
     'groups_users',
-    db.Column('user_id', db.Integer(), db.ForeignKey('users.id')),
-    db.Column('group_id', db.Integer(), db.ForeignKey('groups.id')))
+    db.Column('user_id', db.Integer, db.ForeignKey('users.id'),
+              nullable=False),
+    db.Column('group_id', db.Integer, db.ForeignKey('groups.id'),
+              nullable=False)
+)
 
 
 
 
 class Group(db.Model, CRUDMixin):
 class Group(db.Model, CRUDMixin):
@@ -33,7 +36,7 @@ class Group(db.Model, CRUDMixin):
 
 
     id = db.Column(db.Integer, primary_key=True)
     id = db.Column(db.Integer, primary_key=True)
     name = db.Column(db.String(255), unique=True, nullable=False)
     name = db.Column(db.String(255), unique=True, nullable=False)
-    description = db.Column(db.Text)
+    description = db.Column(db.Text, nullable=True)
 
 
     # Group types
     # Group types
     admin = db.Column(db.Boolean, default=False, nullable=False)
     admin = db.Column(db.Boolean, default=False, nullable=False)
@@ -86,22 +89,24 @@ class User(db.Model, UserMixin, CRUDMixin):
     username = db.Column(db.String(200), unique=True, nullable=False)
     username = db.Column(db.String(200), unique=True, nullable=False)
     email = db.Column(db.String(200), unique=True, nullable=False)
     email = db.Column(db.String(200), unique=True, nullable=False)
     _password = db.Column('password', db.String(120), nullable=False)
     _password = db.Column('password', db.String(120), nullable=False)
-    date_joined = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    lastseen = db.Column(UTCDateTime(timezone=True), default=time_utcnow)
-    birthday = db.Column(db.DateTime)
-    gender = db.Column(db.String(10))
-    website = db.Column(db.String(200))
-    location = db.Column(db.String(100))
-    signature = db.Column(db.Text)
-    avatar = db.Column(db.String(200))
-    notes = db.Column(db.Text)
-
-    last_failed_login = db.Column(UTCDateTime(timezone=True))
-    login_attempts = db.Column(db.Integer, default=0)
-    activated = db.Column(db.Boolean, default=False)
-
-    theme = db.Column(db.String(15))
-    language = db.Column(db.String(15), default="en")
+    date_joined = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                            nullable=False)
+    lastseen = db.Column(UTCDateTime(timezone=True), default=time_utcnow,
+                         nullable=True)
+    birthday = db.Column(db.DateTime, nullable=True)
+    gender = db.Column(db.String(10), nullable=True)
+    website = db.Column(db.String(200), nullable=True)
+    location = db.Column(db.String(100), nullable=True)
+    signature = db.Column(db.Text, nullable=True)
+    avatar = db.Column(db.String(200), nullable=True)
+    notes = db.Column(db.Text, nullable=True)
+
+    last_failed_login = db.Column(UTCDateTime(timezone=True), nullable=True)
+    login_attempts = db.Column(db.Integer, default=0, nullable=False)
+    activated = db.Column(db.Boolean, default=False, nullable=False)
+
+    theme = db.Column(db.String(15), nullable=True)
+    language = db.Column(db.String(15), default="en", nullable=True)
 
 
     posts = db.relationship("Post", backref="user", lazy="dynamic")
     posts = db.relationship("Post", backref="user", lazy="dynamic")
     topics = db.relationship("Topic", backref="user", lazy="dynamic")
     topics = db.relationship("Topic", backref="user", lazy="dynamic")

+ 176 - 0
migrations/933bd7d807c4_add_more_non_nullables.py

@@ -0,0 +1,176 @@
+"""Add more non nullables
+
+Revision ID: 933bd7d807c4
+Revises: d87cea4e995d
+Create Date: 2017-05-04 11:44:16.146471
+
+"""
+from alembic import op
+import sqlalchemy as sa
+import flaskbb
+
+# revision identifiers, used by Alembic.
+revision = '933bd7d807c4'
+down_revision = 'd87cea4e995d'
+branch_labels = ()
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    with op.batch_alter_table('conversations', schema=None) as batch_op:
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+
+    with op.batch_alter_table('forumsread', schema=None) as batch_op:
+        batch_op.alter_column('last_read',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+
+    with op.batch_alter_table('groups_users', schema=None) as batch_op:
+        batch_op.alter_column('group_id',
+               existing_type=sa.INTEGER(),
+               nullable=False)
+        batch_op.alter_column('user_id',
+               existing_type=sa.INTEGER(),
+               nullable=False)
+
+    with op.batch_alter_table('messages', schema=None) as batch_op:
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+
+    with op.batch_alter_table('posts', schema=None) as batch_op:
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+
+    with op.batch_alter_table('reports', schema=None) as batch_op:
+        batch_op.alter_column('post_id',
+               existing_type=sa.INTEGER(),
+               nullable=True)
+        batch_op.alter_column('reported',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+        batch_op.alter_column('reporter_id',
+               existing_type=sa.INTEGER(),
+               nullable=True)
+
+    with op.batch_alter_table('topics', schema=None) as batch_op:
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+        batch_op.alter_column('important',
+               existing_type=sa.BOOLEAN(),
+               nullable=False)
+        batch_op.alter_column('last_updated',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+        batch_op.alter_column('locked',
+               existing_type=sa.BOOLEAN(),
+               nullable=False)
+        batch_op.alter_column('post_count',
+               existing_type=sa.INTEGER(),
+               nullable=False)
+        batch_op.alter_column('views',
+               existing_type=sa.INTEGER(),
+               nullable=False)
+
+    with op.batch_alter_table('topicsread', schema=None) as batch_op:
+        batch_op.alter_column('last_read',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+
+    with op.batch_alter_table('users', schema=None) as batch_op:
+        batch_op.alter_column('activated',
+               existing_type=sa.BOOLEAN(),
+               nullable=False)
+        batch_op.alter_column('date_joined',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=False)
+        batch_op.alter_column('login_attempts',
+               existing_type=sa.INTEGER(),
+               nullable=False)
+
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    with op.batch_alter_table('users', schema=None) as batch_op:
+        batch_op.alter_column('login_attempts',
+               existing_type=sa.INTEGER(),
+               nullable=True)
+        batch_op.alter_column('date_joined',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+        batch_op.alter_column('activated',
+               existing_type=sa.BOOLEAN(),
+               nullable=True)
+
+    with op.batch_alter_table('topicsread', schema=None) as batch_op:
+        batch_op.alter_column('last_read',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+
+    with op.batch_alter_table('topics', schema=None) as batch_op:
+        batch_op.alter_column('views',
+               existing_type=sa.INTEGER(),
+               nullable=True)
+        batch_op.alter_column('post_count',
+               existing_type=sa.INTEGER(),
+               nullable=True)
+        batch_op.alter_column('locked',
+               existing_type=sa.BOOLEAN(),
+               nullable=True)
+        batch_op.alter_column('last_updated',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+        batch_op.alter_column('important',
+               existing_type=sa.BOOLEAN(),
+               nullable=True)
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+
+    with op.batch_alter_table('reports', schema=None) as batch_op:
+        batch_op.alter_column('reporter_id',
+               existing_type=sa.INTEGER(),
+               nullable=False)
+        batch_op.alter_column('reported',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+        batch_op.alter_column('post_id',
+               existing_type=sa.INTEGER(),
+               nullable=False)
+
+    with op.batch_alter_table('posts', schema=None) as batch_op:
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+
+    with op.batch_alter_table('messages', schema=None) as batch_op:
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+
+    with op.batch_alter_table('groups_users', schema=None) as batch_op:
+        batch_op.alter_column('user_id',
+               existing_type=sa.INTEGER(),
+               nullable=True)
+        batch_op.alter_column('group_id',
+               existing_type=sa.INTEGER(),
+               nullable=True)
+
+    with op.batch_alter_table('forumsread', schema=None) as batch_op:
+        batch_op.alter_column('last_read',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+
+    with op.batch_alter_table('conversations', schema=None) as batch_op:
+        batch_op.alter_column('date_created',
+               existing_type=flaskbb.utils.database.UTCDateTime(timezone=True),
+               nullable=True)
+
+    # ### end Alembic commands ###