"""
camcops_server/alembic/versions/0023_comments.py

===============================================================================

    Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CamCOPS.

    CamCOPS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CamCOPS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.

===============================================================================

DATABASE REVISION SCRIPT

Update all comments. LARGE file.

- Required manual modification from MySQL types to SQLAlchemy types.
- In MySQL, check with ``SHOW FULL COLUMNS FROM <tablename>;``.

Revision ID: 0023
Revises: 0022
Creation date: 2019-04-23 19:55:16.914746

"""

# =============================================================================
# Imports
# =============================================================================

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

from camcops_server.cc_modules.cc_sqla_coltypes import (
    PendulumDateTimeAsIsoTextColType,
    SemanticVersionColType,
)


# =============================================================================
# Revision identifiers, used by Alembic.
# =============================================================================

revision = "0023"
down_revision = "0022"
branch_labels = None
depends_on = None


# =============================================================================
# The upgrade/downgrade steps
# =============================================================================


# noinspection PyPep8,PyTypeChecker
def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table("_dirty_tables", schema=None) as batch_op:
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment="Source tablet device ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tablename",
            existing_type=sa.String(length=128),
            comment="Table in the process of being preserved",
            existing_nullable=True,
        )

    with op.batch_alter_table("_emails", schema=None) as batch_op:
        batch_op.alter_column(
            "bcc",
            existing_type=sa.Text(),
            comment="Email 'Bcc:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "body",
            existing_type=sa.Text(),
            comment="Email body",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cc",
            existing_type=sa.Text(),
            comment="Email 'Cc:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "charset",
            existing_type=sa.String(length=64),
            comment="Character set for e-mail body",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "content_type",
            existing_type=sa.String(length=255),
            comment="MIME type for e-mail body",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "created_at_utc",
            existing_type=sa.DateTime(),
            comment="Date/time message was created (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date",
            existing_type=sa.String(length=31),
            comment="Email date in RFC 2822 format",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "from_addr",
            existing_type=sa.Unicode(length=255),
            comment="Email 'From:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "host",
            existing_type=sa.String(length=255),
            comment="Email server",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "msg_string",
            existing_type=sa.UnicodeText().with_variant(
                mysql.LONGTEXT, "mysql"
            ),
            comment="Full encoded e-mail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "port",
            existing_type=sa.Integer(),
            comment="Port number on e-mail server",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "reply_to",
            existing_type=sa.Unicode(length=255),
            comment="Email 'Reply-To:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sender",
            existing_type=sa.Unicode(length=255),
            comment="Email 'Sender:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sending_failure_reason",
            existing_type=sa.Text(),
            comment="Reason for sending failure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sent",
            existing_type=sa.Boolean(),
            comment="Sent?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "sent_at_utc",
            existing_type=sa.DateTime(),
            comment="Date/time message was sent (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subject",
            existing_type=sa.Text(),
            comment="Email 'Subject:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "to",
            existing_type=sa.Text(),
            comment="Email 'To:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "use_tls",
            existing_type=sa.Boolean(),
            comment="Use TLS?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=255),
            comment="Username on e-mail server",
            existing_nullable=True,
        )

    with op.batch_alter_table("_export_recipients", schema=None) as batch_op:
        batch_op.alter_column(
            "all_groups",
            existing_type=sa.Boolean(),
            comment="Export all groups? (If not, see group_ids.)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "current",
            existing_type=sa.Boolean(),
            comment=(
                "Is this the current record for this recipient? (If not, it's"
                " a historical record for audit purposes.)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_add_summaries",
            existing_type=sa.Boolean(),
            comment="(DATABASE) Add summary information?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_echo",
            existing_type=sa.Boolean(),
            comment="(DATABASE) Echo SQL applied to destination database?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_include_blobs",
            existing_type=sa.Boolean(),
            comment="(DATABASE) Include BLOBs?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_patient_id_per_row",
            existing_type=sa.Boolean(),
            comment="(DATABASE) Add patient ID information per row?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_url",
            existing_type=sa.String(length=255),
            comment="(DATABASE) SQLAlchemy database URL for export",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_bcc",
            existing_type=sa.Text(),
            comment='(EMAIL) "BCC:" recipient(s), as a CSV list',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_body",
            existing_type=sa.Text(),
            comment="(EMAIL) Body contents",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_body_as_html",
            existing_type=sa.Boolean(),
            comment="(EMAIL) Is the body HTML, rather than plain text?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "email_cc",
            existing_type=sa.Text(),
            comment='(EMAIL) "CC:" recipient(s), as a CSV list',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_from",
            existing_type=sa.Unicode(length=255),
            comment='(EMAIL) "From:" address(es)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_host",
            existing_type=sa.String(length=255),
            comment="(EMAIL) E-mail (SMTP) server host name/IP address",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_host_username",
            existing_type=sa.String(length=255),
            comment="(EMAIL) Username on e-mail server",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_keep_message",
            existing_type=sa.Boolean(),
            comment="(EMAIL) Keep entire message?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "email_patient",
            existing_type=sa.Unicode(length=255),
            comment="(EMAIL) Patient specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_patient_spec_if_anonymous",
            existing_type=sa.Unicode(length=255),
            comment="(EMAIL) Patient specification for anonymous tasks",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_port",
            existing_type=sa.Integer(),
            comment="(EMAIL) E-mail (SMTP) server port number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_reply_to",
            existing_type=sa.Unicode(length=255),
            comment='(EMAIL) "Reply-To:" address(es)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_sender",
            existing_type=sa.Unicode(length=255),
            comment='(EMAIL) "Sender:" address(es)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_subject",
            existing_type=sa.Unicode(length=255),
            comment="(EMAIL) Subject specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_to",
            existing_type=sa.Text(),
            comment='(EMAIL) "To:" recipient(s), as a CSV list',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_use_tls",
            existing_type=sa.Boolean(),
            comment="(EMAIL) Use explicit TLS connection?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "end_datetime_utc",
            existing_type=sa.DateTime(),
            comment="End date/time for tasks (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_export_rio_metadata",
            existing_type=sa.Boolean(),
            comment="(FILE) Export RiO metadata file along with main file?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "file_filename_spec",
            existing_type=sa.Unicode(length=255),
            comment="(FILE) Filename specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_make_directory",
            existing_type=sa.Boolean(),
            comment=(
                "(FILE) Make destination directory if it doesn't already exist"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "file_overwrite_files",
            existing_type=sa.Boolean(),
            comment="(FILE) Overwrite existing files",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "file_patient_spec",
            existing_type=sa.Unicode(length=255),
            comment="(FILE) Patient part of filename specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_patient_spec_if_anonymous",
            existing_type=sa.Unicode(length=255),
            comment=(
                "(FILE) Patient part of filename specification for anonymous"
                " tasks"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_script_after_export",
            existing_type=sa.Text(),
            comment="(FILE) Command/script to run after file export",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finalized_only",
            existing_type=sa.Boolean(),
            comment="Send only finalized tasks",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "group_ids",
            existing_type=sa.Text(),
            comment=(
                "Integer IDs of CamCOPS group to export data from (as CSV)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_debug_divert_to_file",
            existing_type=sa.Boolean(),
            comment="(HL7 debugging option) Divert messages to files?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_debug_treat_diverted_as_sent",
            existing_type=sa.Boolean(),
            comment=(
                "(HL7 debugging option) Treat messages diverted to file as"
                " sent"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_host",
            existing_type=sa.String(length=255),
            comment="(HL7) Destination host name/IP address",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_keep_message",
            existing_type=sa.Boolean(),
            comment="(HL7) Keep copy of message in database? (May be large!)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_keep_reply",
            existing_type=sa.Boolean(),
            comment="(HL7) Keep copy of server's reply in database?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_network_timeout_ms",
            existing_type=sa.Integer(),
            comment="(HL7) Network timeout (ms).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_ping_first",
            existing_type=sa.Boolean(),
            comment="(HL7) Ping via TCP/IP before sending HL7 messages?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_port",
            existing_type=sa.Integer(),
            comment="(HL7) Destination port number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment="Export recipient ID (arbitrary primary key)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "include_anonymous",
            existing_type=sa.Boolean(),
            comment=(
                "Include anonymous tasks? Not applicable to some methods (e.g."
                " HL7)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "primary_idnum",
            existing_type=sa.Integer(),
            comment="Which ID number is used as the primary ID?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "push",
            existing_type=sa.Boolean(),
            comment="Push (support auto-export on upload)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "recipient_name",
            existing_type=sa.String(length=191),
            comment="Name of export recipient",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "require_idnum_mandatory",
            existing_type=sa.Boolean(),
            comment=(
                "Must the primary ID number be mandatory in the relevant"
                " policy?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rio_document_type",
            existing_type=sa.Text(),
            comment="(FILE / RiO) RiO metadata: document type for RiO",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rio_idnum",
            existing_type=sa.Integer(),
            comment=(
                "(FILE / RiO) RiO metadata: which ID number is the RiO ID?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rio_uploading_user",
            existing_type=sa.Text(),
            comment="(FILE / RiO) RiO metadata: name of automatic upload user",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_datetime_utc",
            existing_type=sa.DateTime(),
            comment="Start date/time for tasks (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_format",
            existing_type=sa.String(length=50),
            comment=(
                "Format that task information should be sent in (e.g. PDF), if"
                " not predetermined by the transmission method"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "transmission_method",
            existing_type=sa.String(length=50),
            comment="Export transmission method (e.g. hl7, file)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "xml_field_comments",
            existing_type=sa.Boolean(),
            comment="Whether to include field comments in XML output",
            existing_nullable=False,
        )

    with op.batch_alter_table("_exported_task_email", schema=None) as batch_op:
        batch_op.alter_column(
            "email_id",
            existing_type=sa.BigInteger(),
            comment="FK to _emails.id",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "exported_task_id",
            existing_type=sa.BigInteger(),
            comment="FK to _exported_tasks.id",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )

    with op.batch_alter_table(
        "_exported_task_filegroup", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "exported_task_id",
            existing_type=sa.BigInteger(),
            comment="FK to _exported_tasks.id",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "filenames",
            existing_type=sa.Text(),
            comment="List of filenames exported",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "script_called",
            existing_type=sa.Boolean(),
            comment="Was the FILE_SCRIPT_AFTER_EXPORT script called?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "script_retcode",
            existing_type=sa.Integer(),
            comment="Return code from the FILE_SCRIPT_AFTER_EXPORT script",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "script_stderr",
            existing_type=sa.Text(),
            comment="stderr from the FILE_SCRIPT_AFTER_EXPORT script",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "script_stdout",
            existing_type=sa.Text(),
            comment="stdout from the FILE_SCRIPT_AFTER_EXPORT script",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "_exported_task_hl7msg", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "exported_task_id",
            existing_type=sa.BigInteger(),
            comment="FK to _exported_tasks.id",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "failure_reason",
            existing_type=sa.Text(),
            comment="Reason for failure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "message",
            existing_type=sa.UnicodeText().with_variant(
                mysql.LONGTEXT, "mysql"
            ),
            comment="Message body, if kept",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "reply",
            existing_type=sa.Text(),
            comment="Server's reply, if kept",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "reply_at_utc",
            existing_type=sa.DateTime(),
            comment="Time message was replied to (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sent_at_utc",
            existing_type=sa.DateTime(),
            comment="Time message was sent at (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "success",
            existing_type=sa.Boolean(),
            comment="Message sent successfully and acknowledged by HL7 server",
            existing_nullable=True,
        )

    with op.batch_alter_table("_exported_tasks", schema=None) as batch_op:
        batch_op.alter_column(
            "basetable",
            existing_type=sa.String(length=128),
            comment="Base table of task concerned",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "cancelled",
            existing_type=sa.Boolean(),
            comment=(
                "Export subsequently cancelled/invalidated (may trigger"
                " resend)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "cancelled_at_utc",
            existing_type=sa.DateTime(),
            comment="Time export was cancelled at (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "failure_reasons",
            existing_type=sa.Text(),
            comment="Reasons for failure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finish_at_utc",
            existing_type=sa.DateTime(),
            comment="Time export was finished (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "recipient_id",
            existing_type=sa.BigInteger(),
            comment="FK to _export_recipients.id",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "start_at_utc",
            existing_type=sa.DateTime(),
            comment="Time export was started (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "success",
            existing_type=sa.Boolean(),
            comment="Task exported successfully?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "task_server_pk",
            existing_type=sa.Integer(),
            comment="Server PK of task in basetable (_pk field)",
            existing_nullable=False,
        )

    with op.batch_alter_table("_idnum_definitions", schema=None) as batch_op:
        batch_op.alter_column(
            "description",
            existing_type=sa.Unicode(length=255),
            comment="Full description of the ID number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_assigning_authority",
            existing_type=sa.String(length=20),
            comment=(
                "HL7: Assigning Authority for ID number (unique name of the"
                " system/organization/agency/department that creates the"
                " data)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_id_type",
            existing_type=sa.String(length=5),
            comment=(
                "HL7: Identifier Type code: 'a code corresponding to the type"
                " of identifier. In some cases, this code may be used as a"
                ' qualifier to the "Assigning Authority" component.\''
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "short_description",
            existing_type=sa.Unicode(length=255),
            comment="Short description of the ID number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "validation_method",
            existing_type=sa.String(length=50),
            comment="Optional validation method",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "which_idnum",
            existing_type=sa.Integer(),
            comment="Which of the server's ID numbers is this?",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )

    with op.batch_alter_table("_idnum_index", schema=None) as batch_op:
        batch_op.alter_column(
            "idnum_pk",
            existing_type=sa.Integer(),
            comment=(
                "Server primary key of the PatientIdNum (and of the"
                " PatientIdNumIndexEntry)"
            ),
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "idnum_value",
            existing_type=sa.BigInteger(),
            comment="The value of the ID number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "indexed_at_utc",
            existing_type=sa.DateTime(),
            comment="When this index entry was created",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_pk",
            existing_type=sa.Integer(),
            comment="Server primary key of the Patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "which_idnum",
            existing_type=sa.Integer(),
            comment="Which of the server's ID numbers is this?",
            existing_nullable=False,
        )

    with op.batch_alter_table(
        "_security_account_lockouts", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "locked_until",
            existing_type=sa.DateTime(),
            comment="Account is locked until (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=191),
            comment=(
                "User name (which may be a non-existent user, to prevent"
                " subtle username discovery by careful timing)"
            ),
            existing_nullable=False,
        )

    with op.batch_alter_table("_security_audit", schema=None) as batch_op:
        batch_op.alter_column(
            "details",
            existing_type=sa.Text(),
            comment="Details of the access",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment="Device ID, where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "patient_server_pk",
            existing_type=sa.Integer(),
            comment=(
                "Server PK of the patient (patient._pk) concerned, or NULL if"
                " not applicable"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "remote_addr",
            existing_type=sa.String(length=45),
            comment="IP address of the remote computer",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "server_pk",
            existing_type=sa.Integer(),
            comment="Server PK (table._pk), where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "source",
            existing_type=sa.String(length=20),
            comment="Source (e.g. tablet, webviewer)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "table_name",
            existing_type=sa.String(length=128),
            comment="Table involved, where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "user_id",
            existing_type=sa.Integer(),
            comment="ID of user, where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_access_utc",
            existing_type=sa.DateTime(),
            comment="Date/time of access (UTC)",
            existing_nullable=False,
        )

    with op.batch_alter_table("_security_devices", schema=None) as batch_op:
        batch_op.alter_column(
            "camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="CamCOPS version number on the tablet device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "currently_preserving",
            existing_type=sa.Boolean(),
            comment="Preservation currently in progress",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "friendly_name",
            existing_type=sa.Text(),
            comment="Friendly name of the device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="ID of the source tablet device",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "last_upload_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "Date/time when the device's last upload batch started (UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "name",
            existing_type=sa.String(length=191),
            comment="Short cryptic unique name of the source tablet device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ongoing_upload_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "Date/time when the device's ongoing upload batch started"
                " (UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "registered_by_user_id",
            existing_type=sa.Integer(),
            comment="ID of user that registered the device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "uploading_user_id",
            existing_type=sa.Integer(),
            comment="ID of user in the process of uploading right now",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_registered_utc",
            existing_type=sa.DateTime(),
            comment="Date/time when the device was registered (UTC)",
            existing_nullable=True,
        )

    with op.batch_alter_table("_security_groups", schema=None) as batch_op:
        batch_op.alter_column(
            "description",
            existing_type=sa.Unicode(length=255),
            comment="Description of the group",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finalize_policy",
            existing_type=sa.String(length=255),
            comment="Finalize policy for the group, as a string",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="Group ID",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "name",
            existing_type=sa.Unicode(length=191),
            comment="Group name",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "upload_policy",
            existing_type=sa.String(length=255),
            comment="Upload policy for the group, as a string",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "_security_login_failures", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "login_failure_at",
            existing_type=sa.DateTime(),
            comment="Login failure occurred at (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=191),
            comment=(
                "User name (which may be a non-existent user, to prevent"
                " subtle username discovery by careful timing)"
            ),
            existing_nullable=False,
        )

    with op.batch_alter_table("_security_user_group", schema=None) as batch_op:
        batch_op.alter_column(
            "groupadmin",
            existing_type=sa.Boolean(),
            comment="Is the user a privileged administrator for this group?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_add_notes",
            existing_type=sa.Boolean(),
            comment="May the user add special notes to tasks?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_dump_data",
            existing_type=sa.Boolean(),
            comment=(
                "May the user run database data dumps via the web interface?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_register_devices",
            existing_type=sa.Boolean(),
            comment="May the user register tablet devices?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_run_reports",
            existing_type=sa.Boolean(),
            comment=(
                "May the user run reports via the web interface? (Overrides"
                " other view restrictions.)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_upload",
            existing_type=sa.Boolean(),
            comment="May the user upload data from a tablet device?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_use_webviewer",
            existing_type=sa.Boolean(),
            comment="May the user use the web front end to view CamCOPS data?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "view_all_patients_when_unfiltered",
            existing_type=sa.Boolean(),
            comment=(
                "When no record filters are applied, can the user see all"
                " records? (If not, then none are shown.)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("_security_users", schema=None) as batch_op:
        batch_op.alter_column(
            "email",
            existing_type=sa.Unicode(length=255),
            comment="User's e-mail address",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fullname",
            existing_type=sa.Unicode(length=255),
            comment="User's full name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hashedpw",
            existing_type=sa.String(length=60),
            comment="Password hash",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="User ID",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "last_login_at_utc",
            existing_type=sa.DateTime(),
            comment="Date/time this user last logged in (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_password_change_utc",
            existing_type=sa.DateTime(),
            comment="Date/time this user last changed their password (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "must_change_password",
            existing_type=sa.Boolean(),
            comment="Must change password at next webview login",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "superuser",
            existing_type=sa.Boolean(),
            comment="Superuser?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "upload_group_id",
            existing_type=sa.Integer(),
            comment="ID of the group to which this user uploads at present",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=191),
            comment="User name",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_agreed_terms_of_use",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "Date/time this user acknowledged the Terms and Conditions of"
                " Use (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "_security_webviewer_sessions", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="Session ID (internal number for insertion speed)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "ip_address",
            existing_type=sa.String(length=45),
            comment="IP address of user",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_activity_utc",
            existing_type=sa.DateTime(),
            comment="Date/time of last activity (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "number_to_view",
            existing_type=sa.Integer(),
            comment="Number of records to view",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_filter_id",
            existing_type=sa.Integer(),
            comment="Task filter ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "token",
            existing_type=sa.String(length=88),
            comment="Token (base 64 encoded random number)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "user_id",
            existing_type=sa.Integer(),
            comment="User ID",
            existing_nullable=True,
        )

    with op.batch_alter_table("_server_settings", schema=None) as batch_op:
        batch_op.alter_column(
            "database_title",
            existing_type=sa.Unicode(length=255),
            comment="Database title",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=(
                "PK (arbitrary integer but only a value of 1 is ever used)"
            ),
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "last_dummy_login_failure_clearance_at_utc",
            existing_type=sa.DateTime(),
            comment=(
                "Date/time (in UTC) when login failure records were cleared"
                " for nonexistent users (security feature)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("_special_notes", schema=None) as batch_op:
        batch_op.alter_column(
            "basetable",
            existing_type=sa.String(length=128),
            comment="Base table of task concerned (part of FK)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment="Source tablet device (part of FK)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "era",
            existing_type=sa.String(length=32),
            comment="Era (part of FK)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hidden",
            existing_type=sa.Boolean(),
            existing_comment="Manually hidden (effectively: deleted)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "note",
            existing_type=sa.Text(),
            comment="Special note, added manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "note_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Date/time of note entry (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "note_id",
            existing_type=sa.Integer(),
            comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "task_id",
            existing_type=sa.Integer(),
            comment=(
                "Client-side ID of the task, or patient, concerned (part"
                " of FK)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "user_id",
            existing_type=sa.Integer(),
            comment="User that entered this note",
            existing_nullable=True,
        )

    with op.batch_alter_table("_task_filters", schema=None) as batch_op:
        batch_op.alter_column(
            "complete_only",
            existing_type=sa.Boolean(),
            comment="Task filter: task complete?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "device_ids",
            existing_type=sa.Text(),
            comment="Task filter: source device ID(s), as CSV",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dob",
            existing_type=sa.DATE(),
            comment="Task filter: DOB",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "end_datetime_iso8601",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Task filter: end date/time (UTC as ISO8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "forename",
            existing_type=sa.Unicode(length=255),
            comment="Task filter: forename",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "group_ids",
            existing_type=sa.Text(),
            comment="Task filter: group ID(s), as CSV",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="Task filter ID (arbitrary integer)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "idnum_criteria",
            existing_type=sa.Text(),
            comment=(
                "ID filters as JSON; the ID number definitions are joined"
                " with OR"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sex",
            existing_type=sa.String(length=1),
            comment="Task filter: sex",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_datetime_iso8601",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Task filter: start date/time (UTC as ISO8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "surname",
            existing_type=sa.Unicode(length=255),
            comment="Task filter: surname",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_types",
            existing_type=sa.Text(),
            comment="Task filter: task type(s), as CSV list of table names",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tasks_offering_trackers_only",
            existing_type=sa.Boolean(),
            comment="Task filter: restrict to tasks offering trackers only?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tasks_with_patient_only",
            existing_type=sa.Boolean(),
            comment=(
                "Task filter: restrict to tasks with a patient (non-anonymous"
                " tasks) only?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "text_contents",
            existing_type=sa.Text(),
            comment="Task filter: filter text fields",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "user_ids",
            existing_type=sa.Text(),
            comment="Task filter: adding (uploading) user ID(s), as CSV",
            existing_nullable=True,
        )

    with op.batch_alter_table("_task_index", schema=None) as batch_op:
        batch_op.alter_column(
            "adding_user_id",
            existing_type=sa.Integer(),
            comment="ID of user that added this task",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment="ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "era",
            existing_type=sa.String(length=32),
            comment="Era (_era) field of the source record",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "group_id",
            existing_type=sa.Integer(),
            comment="ID of group to which this task belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "index_entry_pk",
            existing_type=sa.Integer(),
            comment="Arbitrary primary key of this index entry",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "indexed_at_utc",
            existing_type=sa.DateTime(),
            comment="When this index entry was created",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_pk",
            existing_type=sa.Integer(),
            comment="Server primary key of the patient (if applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_is_complete",
            existing_type=sa.Boolean(),
            comment=(
                "Is the task complete (as judged by the server when the index"
                " entry was created)?"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "task_pk",
            existing_type=sa.Integer(),
            comment="Server primary key of the task",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_table_name",
            existing_type=sa.String(length=128),
            comment="Table name of the task's base table",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment="Date/time this task index was uploaded (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created_iso",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Date/time this task instance was created (ISO 8601)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created_utc",
            existing_type=sa.DateTime(),
            comment="Date/time this task instance was created (UTC)",
            existing_nullable=False,
        )

    with op.batch_alter_table("ace3", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "age_at_leaving_full_time_education",
            existing_type=sa.Integer(),
            comment="Age at leaving full time education",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_num_registration_trials",
            existing_type=sa.Integer(),
            comment="Attention, repetition, number of trials (not scored)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place1",
            existing_type=sa.Integer(),
            comment="Attention, place, 1/5, house number/floor (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place2",
            existing_type=sa.Integer(),
            comment="Attention, place, 2/5, street/hospital (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place3",
            existing_type=sa.Integer(),
            comment="Attention, place, 3/5, town (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place4",
            existing_type=sa.Integer(),
            comment="Attention, place, 4/5, county (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place5",
            existing_type=sa.Integer(),
            comment="Attention, place, 5/5, country (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_repeat_word1",
            existing_type=sa.Integer(),
            comment="Attention, repeat word, 1/3, lemon (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_repeat_word2",
            existing_type=sa.Integer(),
            comment="Attention, repeat word, 2/3, key (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_repeat_word3",
            existing_type=sa.Integer(),
            comment="Attention, repeat word, 3/3, ball (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction1",
            existing_type=sa.Integer(),
            comment="Attention, serial sevens, 1/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction2",
            existing_type=sa.Integer(),
            comment="Attention, serial sevens, 2/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction3",
            existing_type=sa.Integer(),
            comment="Attention, serial sevens, 3/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction4",
            existing_type=sa.Integer(),
            comment="Attention, serial sevens, 4/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction5",
            existing_type=sa.Integer(),
            comment="Attention, serial sevens, 5/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time1",
            existing_type=sa.Integer(),
            comment="Attention, time, 1/5, day (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time2",
            existing_type=sa.Integer(),
            comment="Attention, time, 2/5, date (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time3",
            existing_type=sa.Integer(),
            comment="Attention, time, 3/5, month (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time4",
            existing_type=sa.Integer(),
            comment="Attention, time, 4/5, year (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time5",
            existing_type=sa.Integer(),
            comment="Attention, time, 5/5, season (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fluency_animals_score",
            existing_type=sa.Integer(),
            comment="Fluency, animals, score 0-7",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fluency_letters_score",
            existing_type=sa.Integer(),
            comment="Fluency, words beginning with P, score 0-7",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "handedness",
            existing_type=sa.String(length=1),
            comment="Handedness (L or R)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "lang_follow_command1",
            existing_type=sa.Integer(),
            comment="Language, command 1/3 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_follow_command2",
            existing_type=sa.Integer(),
            comment="Language, command 2/3 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_follow_command3",
            existing_type=sa.Integer(),
            comment="Language, command 3/3 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_follow_command_practice",
            existing_type=sa.Integer(),
            comment="Language, command, practice trial (not scored)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept1",
            existing_type=sa.Integer(),
            comment="Language, identify concept, 1/4, monarchy (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept2",
            existing_type=sa.Integer(),
            comment="Language, identify concept, 2/4, marsupial (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept3",
            existing_type=sa.Integer(),
            comment="Language, identify concept, 3/4, Antarctic (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept4",
            existing_type=sa.Integer(),
            comment="Language, identify concept, 4/4, nautical (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture1",
            existing_type=sa.Integer(),
            comment="Language, name picture, 1/12, spoon (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture10",
            existing_type=sa.Integer(),
            comment="Language, name picture, 10/12, crown (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture11",
            existing_type=sa.Integer(),
            comment=(
                "Language, name picture, 11/12, alligator/crocodile (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture12",
            existing_type=sa.Integer(),
            comment=(
                "Language, name picture, 12/12, accordion/piano"
                " accordion/squeeze box (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture2",
            existing_type=sa.Integer(),
            comment="Language, name picture, 2/12, book (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture3",
            existing_type=sa.Integer(),
            comment="Language, name picture, 3/12, kangaroo/wallaby (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture4",
            existing_type=sa.Integer(),
            comment="Language, name picture, 4/12, penguin (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture5",
            existing_type=sa.Integer(),
            comment="Language, name picture, 5/12, anchor (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture6",
            existing_type=sa.Integer(),
            comment="Language, name picture, 6/12, camel/dromedary (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture7",
            existing_type=sa.Integer(),
            comment="Language, name picture, 7/12, harp (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture8",
            existing_type=sa.Integer(),
            comment="Language, name picture, 8/12, rhinoceros (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture9",
            existing_type=sa.Integer(),
            comment="Language, name picture, 9/12, barrel/keg/tub (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_read_words_aloud",
            existing_type=sa.Integer(),
            comment="Language, read five irregular words (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_sentence1",
            existing_type=sa.Integer(),
            comment="Language, repeat sentence, 1/2, glitters_gold (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_sentence2",
            existing_type=sa.Integer(),
            comment="Language, repeat sentence, 2/2, stitch_time (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word1",
            existing_type=sa.Integer(),
            comment="Language, repeat word, 1/4, caterpillar (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word2",
            existing_type=sa.Integer(),
            comment="Language, repeat word, 2/4, eccentricity (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word3",
            existing_type=sa.Integer(),
            comment="Language, repeat word, 3/4, unintelligible (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word4",
            existing_type=sa.Integer(),
            comment="Language, repeat word, 4/4, statistician (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_write_sentences_point1",
            existing_type=sa.Integer(),
            comment=(
                "Language, write sentences, 1/2, two sentences on same topic"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_write_sentences_point2",
            existing_type=sa.Integer(),
            comment=(
                "Language, write sentences, 2/2, grammar/spelling (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous1",
            existing_type=sa.Integer(),
            comment="Memory, famous people, 1/4, current PM (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous2",
            existing_type=sa.Integer(),
            comment="Memory, famous people, 2/4, woman PM (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous3",
            existing_type=sa.Integer(),
            comment="Memory, famous people, 3/4, USA president (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous4",
            existing_type=sa.Integer(),
            comment="Memory, famous people, 4/4, JFK (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address1",
            existing_type=sa.Integer(),
            comment="Memory, recall address 1/7, forename (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address2",
            existing_type=sa.Integer(),
            comment="Memory, recall address 2/7, surname (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address3",
            existing_type=sa.Integer(),
            comment="Memory, recall address 3/7, number (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address4",
            existing_type=sa.Integer(),
            comment="Memory, recall address 4/7, street_1 (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address5",
            existing_type=sa.Integer(),
            comment="Memory, recall address 5/7, street_2 (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address6",
            existing_type=sa.Integer(),
            comment="Memory, recall address 6/7, town (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address7",
            existing_type=sa.Integer(),
            comment="Memory, recall address 7/7, county (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_word1",
            existing_type=sa.Integer(),
            comment="Memory, recall word, 1/3, lemon (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_word2",
            existing_type=sa.Integer(),
            comment="Memory, recall word, 2/3, key (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_word3",
            existing_type=sa.Integer(),
            comment="Memory, recall word, 3/3, ball (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address1",
            existing_type=sa.Integer(),
            comment=(
                "Memory, recognize address 1/5 (if applicable) (name) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address2",
            existing_type=sa.Integer(),
            comment=(
                "Memory, recognize address 2/5 (if applicable) (number) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address3",
            existing_type=sa.Integer(),
            comment=(
                "Memory, recognize address 3/5 (if applicable) (street) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address4",
            existing_type=sa.Integer(),
            comment=(
                "Memory, recognize address 4/5 (if applicable) (town) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address5",
            existing_type=sa.Integer(),
            comment=(
                "Memory, recognize address 5/5 (if applicable) (county) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice1",
            existing_type=sa.String(length=1),
            comment=(
                "Memory, recognize address 1/5, CHOICE (if applicable) (name)"
                " (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice2",
            existing_type=sa.String(length=1),
            comment=(
                "Memory, recognize address 2/5, CHOICE (if applicable)"
                " (number) (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice3",
            existing_type=sa.String(length=1),
            comment=(
                "Memory, recognize address 3/5, CHOICE (if applicable)"
                " (street) (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice4",
            existing_type=sa.String(length=1),
            comment=(
                "Memory, recognize address 4/5, CHOICE (if applicable) (town)"
                " (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice5",
            existing_type=sa.String(length=1),
            comment=(
                "Memory, recognize address 5/5, CHOICE (if applicable)"
                " (county) (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_1",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 1/3 (not scored), forename"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_2",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 1/3 (not scored), surname"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_3",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 1/3 (not scored), number"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_4",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 1/3 (not scored), street_1"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_5",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 1/3 (not scored), street_2"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_6",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 1/3 (not scored), town (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_7",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 1/3 (not scored), county"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_1",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 2/3 (not scored), forename"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_2",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 2/3 (not scored), surname"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_3",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 2/3 (not scored), number"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_4",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 2/3 (not scored), street_1"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_5",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 2/3 (not scored), street_2"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_6",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 2/3 (not scored), town (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_7",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 2/3 (not scored), county"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_1",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 3/3 (scored), forename (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_2",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 3/3 (scored), surname (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_3",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 3/3 (scored), number (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_4",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 3/3 (scored), street_1 (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_5",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 3/3 (scored), street_2 (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_6",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 3/3 (scored), town (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_7",
            existing_type=sa.Integer(),
            comment=(
                "Memory, address registration trial 3/3 (scored), county (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "occupation",
            existing_type=sa.Text(),
            comment="Occupation",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "picture1_blobid",
            existing_type=sa.Integer(),
            comment="Photo 1/2 PNG BLOB ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "picture1_rotation",
            existing_type=sa.Integer(),
            comment="Photo 1/2 rotation (degrees clockwise)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "picture2_blobid",
            existing_type=sa.Integer(),
            comment="Photo 2/2 PNG BLOB ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "picture2_rotation",
            existing_type=sa.Integer(),
            comment="Photo 2/2 rotation (degrees clockwise)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_copy_cube",
            existing_type=sa.Integer(),
            comment="Visuospatial, copy cube (0-2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_copy_infinity",
            existing_type=sa.Integer(),
            comment="Visuospatial, copy infinity (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots1",
            existing_type=sa.Integer(),
            comment="Visuospatial, count dots 1/4, 8 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots2",
            existing_type=sa.Integer(),
            comment="Visuospatial, count dots 2/4, 10 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots3",
            existing_type=sa.Integer(),
            comment="Visuospatial, count dots 3/4, 7 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots4",
            existing_type=sa.Integer(),
            comment="Visuospatial, count dots 4/4, 9 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_draw_clock",
            existing_type=sa.Integer(),
            comment="Visuospatial, draw clock (0-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_identify_letter1",
            existing_type=sa.Integer(),
            comment="Visuospatial, identify letter 1/4, K (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_identify_letter2",
            existing_type=sa.Integer(),
            comment="Visuospatial, identify letter 2/4, M (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_identify_letter3",
            existing_type=sa.Integer(),
            comment="Visuospatial, identify letter 3/4, A (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_identify_letter4",
            existing_type=sa.Integer(),
            comment="Visuospatial, identify letter 4/4, T (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("aims", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, facial_expression (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, awareness (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, problems_teeth_dentures (not scored) (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, usually_wears_dentures (not scored) (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, lips (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, jaw (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, tongue (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, upper_limbs (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, lower_limbs (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, trunk (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, global (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, incapacitation (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("apeqpt", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1_choice",
            existing_type=sa.Integer(),
            comment="Enough information was provided (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_satisfaction",
            existing_type=sa.Integer(),
            comment=(
                "Patient satisfaction (0 not at all satisfied - 4 completely"
                " satisfied)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_choice",
            existing_type=sa.Integer(),
            comment="Treatment preference (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_satisfaction",
            existing_type=sa.Text(),
            comment="Service experience",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_choice",
            existing_type=sa.Integer(),
            comment="Preference offered (0 no, 1 yes, 2 N/A)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_datetime",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Date/time the assessment tool was completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("audit", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, how often drink (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, others concerned (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, drinks per day (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, how often six drinks (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, unable to stop (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, unable to do what was expected (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, eye opener (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, guilt (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, unable to remember (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, injuries (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("audit_c", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, how often drink (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, drinks per day (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, how often six drinks (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("badls", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=(
                "Q1, food ('a' best [0] to 'd' worst [3]; 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=(
                "Q10, transfers ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment=(
                "Q11, mobility ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment=(
                "Q12, orientation: time ('a' best [0] to 'd' worst [3];"
                " 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment=(
                "Q13, orientation: space ('a' best [0] to 'd' worst [3];"
                " 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment=(
                "Q14, communication ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment=(
                "Q15, telephone ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.String(length=1),
            comment=(
                "Q16, hosuework/gardening ('a' best [0] to 'd' worst [3];"
                " 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.String(length=1),
            comment=(
                "Q17, shopping ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.String(length=1),
            comment=(
                "Q18, finances ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.String(length=1),
            comment=(
                "Q19, games/hobbies ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=(
                "Q2, eating ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.String(length=1),
            comment=(
                "Q20, transport ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=(
                "Q3, drink ('a' best [0] to 'd' worst [3]; 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=(
                "Q4, drinking ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment=(
                "Q5, dressing ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=(
                "Q6, hygiene ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment=(
                "Q7, teeth ('a' best [0] to 'd' worst [3]; 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment=(
                "Q8, bath/shower ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment=(
                "Q9, toilet/commode ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("bdi", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bdi_scale",
            existing_type=sa.String(length=10),
            comment="Which BDI scale (BDI-I, BDI-IA, BDI-II)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 [BDI-I: mood; BDI-IA: sadness; BDI-II: sadness] (0-3,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 [BDI-I: crying; BDI-IA: crying; BDI-II: crying] (0-3,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 [BDI-I: irritability; BDI-IA: irritability; BDI-II:"
                " agitation] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 [BDI-I: social withdrawal; BDI-IA: social withdrawal;"
                " BDI-II: loss of interest] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 [BDI-I: indecisiveness; BDI-IA: indecisiveness; BDI-II:"
                " indecisiveness] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 [BDI-I: distortion of body image; BDI-IA: body image"
                " change; BDI-II: worthlessness] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 [BDI-I: work inhibition; BDI-IA: work difficulty; BDI-II:"
                " loss of energy] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 [BDI-I: sleep disturbance; BDI-IA: insomnia; BDI-II:"
                " changes in sleeping pattern] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 [BDI-I: fatigability; BDI-IA: fatigability; BDI-II:"
                " irritability] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 [BDI-I: loss of appetite; BDI-IA: loss of appetite;"
                " BDI-II: changes in appetite] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 [BDI-I: weight loss; BDI-IA: weight loss; BDI-II:"
                " concentration difficulty] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 [BDI-I: pessimism; BDI-IA: pessimism; BDI-II: pessimism]"
                " (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 [BDI-I: somatic preoccupation; BDI-IA: somatic"
                " preoccupation; BDI-II: tiredness or fatigue] (0-3, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 [BDI-I: loss of libido; BDI-IA: loss of libido; BDI-II:"
                " loss of interest in sex] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 [BDI-I: sense of failure; BDI-IA: sense of failure;"
                " BDI-II: past failure] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 [BDI-I: lack of satisfaction; BDI-IA:"
                " self-dissatisfaction; BDI-II: loss of pleasure] (0-3, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 [BDI-I: guilt feelings; BDI-IA: guilt; BDI-II: guilty"
                " feelings] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 [BDI-I: sense of punishment; BDI-IA: punishment; BDI-II:"
                " punishment feelings] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 [BDI-I: self-dislike; BDI-IA: self-dislike; BDI-II:"
                " self-dislike] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 [BDI-I: self-accusation; BDI-IA: self-accusations; BDI-II:"
                " self-criticalness] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 [BDI-I: suicidal wishes; BDI-IA: suicidal ideas; BDI-II:"
                " suicidal thoughts or wishes] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("blobs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fieldname",
            existing_type=sa.String(length=128),
            comment="Field name of the field referring to this BLOB by ID",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "filename",
            existing_type=sa.Text(),
            comment=(
                "Filename of the BLOB on the source tablet device (on the"
                " source device, BLOBs are stored in files, not in the"
                " database)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=(
                "BLOB (binary large object) primary key on the source tablet"
                " device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "image_rotation_deg_cw",
            existing_type=sa.Integer(),
            comment=(
                "For images: rotation to be applied, clockwise, in degrees"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mimetype",
            existing_type=sa.String(length=255),
            comment="MIME type of the BLOB",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tablename",
            existing_type=sa.String(length=128),
            comment="Name of the table referring to this BLOB",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "tablepk",
            existing_type=sa.Integer(),
            comment=(
                "Client-perspective primary key (id field) of the row"
                " referring to this BLOB"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "theblob",
            existing_type=sa.LargeBinary().with_variant(
                mysql.LONGBLOB, "mysql"
            ),
            comment=(
                "The BLOB itself, a binary object containing arbitrary"
                " information (such as a picture)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("bmi", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment="Clinician's comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "height_m",
            existing_type=sa.Float(),
            comment="height (m)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mass_kg",
            existing_type=sa.Float(),
            comment="mass (kg)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("bprs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1, somatic concern (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, hostility (1-7, higher worse, 0 for unable to rate)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11, suspiciousness (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12, hallucinatory behaviour (1-7, higher worse, 0 for unable"
                " to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13, motor retardation (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14, uncooperativeness (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15, unusual thought content (1-7, higher worse, 0 for unable"
                " to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16, blunted affect (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17, excitement (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18, disorientation (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19, severity of illness (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, anxiety (1-7, higher worse, 0 for unable to rate)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20, global improvement (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3, emotional withdrawal (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4, conceptual disorganisation (1-7, higher worse, 0 for"
                " unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, guilt (1-7, higher worse, 0 for unable to rate)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, tension (1-7, higher worse, 0 for unable to rate)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7, mannerisms/posturing (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8, grandiosity (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9, depressive mood (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("bprse", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1, somatic concern (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10, hallucinations (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11, unusual thought content (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12, bizarre behaviour (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13, self-neglect (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14, disorientation (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15, conceptual disorganisation (1-7, higher worse, or 0 for"
                " not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16, blunted affect (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17, emotional withdrawal (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18, motor retardation (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment="Q19, tension (1-7, higher worse, or 0 for not assessed)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, anxiety (1-7, higher worse, or 0 for not assessed)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20, uncooperativeness (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21, excitement (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=(
                "Q22, distractibility (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=(
                "Q23, motor hyperactivity (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=(
                "Q24, mannerisms and posturing (1-7, higher worse, or 0 for"
                " not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3, depression (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4, suicidality (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, guilt (1-7, higher worse, or 0 for not assessed)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, hostility (1-7, higher worse, or 0 for not assessed)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7, elevated mood (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8, grandiosity (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9, suspiciousness (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cage", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment="Q1, C (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment="Q2, A (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment="Q3, G (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment="Q4, E (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cape42", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (sad): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (conspiracy): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (destined for importance): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (no future): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (special/unusual person): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (no longer want to live): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (telepathy): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (no interest being with others): distress (1 not, 2 a"
                " bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (electrical devices influence thinking): distress (1 not,"
                " 2 a bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (lacking motivation): distress (1 not, 2 a bit, 3 quite,"
                " 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (cry about nothing): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (double meaning): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (occult): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (lack energy): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress22",
            existing_type=sa.Integer(),
            comment=(
                "Q22 (people look oddly because of appearance): distress (1"
                " not, 2 a bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress23",
            existing_type=sa.Integer(),
            comment=(
                "Q23 (mind empty): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress24",
            existing_type=sa.Integer(),
            comment=(
                "Q24 (thoughts removed): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress25",
            existing_type=sa.Integer(),
            comment=(
                "Q25 (do nothing): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress26",
            existing_type=sa.Integer(),
            comment=(
                "Q26 (thoughts not own): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress27",
            existing_type=sa.Integer(),
            comment=(
                "Q27 (feelings lacking intensity): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress28",
            existing_type=sa.Integer(),
            comment=(
                "Q28 (others might hear thoughts): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress29",
            existing_type=sa.Integer(),
            comment=(
                "Q29 (lack spontaneity): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (not very animated): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress30",
            existing_type=sa.Integer(),
            comment=(
                "Q30 (thought echo): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress31",
            existing_type=sa.Integer(),
            comment=(
                "Q31 (controlled by other force): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress32",
            existing_type=sa.Integer(),
            comment=(
                "Q32 (emotions blunted): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress33",
            existing_type=sa.Integer(),
            comment=(
                "Q33 (hear voices): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress34",
            existing_type=sa.Integer(),
            comment=(
                "Q34 (hear voices conversing): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress35",
            existing_type=sa.Integer(),
            comment=(
                "Q35 (neglecting appearance/hygiene): distress (1 not, 2 a"
                " bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress36",
            existing_type=sa.Integer(),
            comment=(
                "Q36 (never get things done): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress37",
            existing_type=sa.Integer(),
            comment=(
                "Q37 (few hobbies/interests): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress38",
            existing_type=sa.Integer(),
            comment=(
                "Q38 (feel guilty): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress39",
            existing_type=sa.Integer(),
            comment=(
                "Q39 (feel a failure): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (not a talker): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress40",
            existing_type=sa.Integer(),
            comment=(
                "Q40 (tense): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress41",
            existing_type=sa.Integer(),
            comment=(
                "Q41 (Capgras): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress42",
            existing_type=sa.Integer(),
            comment=(
                "Q42 (see things others cannot): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (magazines/TV personal): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (some people not what they seem): distress (1 not, 2 a"
                " bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (persecuted): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (few/no emotions): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (pessimistic): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (sad): frequency? (1 never, 2 sometimes, 3 often, 4 nearly"
                " always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (conspiracy): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (destined for importance): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (no future): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (special/unusual person): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (no longer want to live): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (telepathy): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (no interest being with others): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (electrical devices influence thinking): frequency? (1"
                " never, 2 sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (lacking motivation): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (cry about nothing): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (double meaning): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (occult): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (lack energy): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency22",
            existing_type=sa.Integer(),
            comment=(
                "Q22 (people look oddly because of appearance): frequency? (1"
                " never, 2 sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency23",
            existing_type=sa.Integer(),
            comment=(
                "Q23 (mind empty): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency24",
            existing_type=sa.Integer(),
            comment=(
                "Q24 (thoughts removed): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency25",
            existing_type=sa.Integer(),
            comment=(
                "Q25 (do nothing): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency26",
            existing_type=sa.Integer(),
            comment=(
                "Q26 (thoughts not own): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency27",
            existing_type=sa.Integer(),
            comment=(
                "Q27 (feelings lacking intensity): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency28",
            existing_type=sa.Integer(),
            comment=(
                "Q28 (others might hear thoughts): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency29",
            existing_type=sa.Integer(),
            comment=(
                "Q29 (lack spontaneity): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (not very animated): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency30",
            existing_type=sa.Integer(),
            comment=(
                "Q30 (thought echo): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency31",
            existing_type=sa.Integer(),
            comment=(
                "Q31 (controlled by other force): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency32",
            existing_type=sa.Integer(),
            comment=(
                "Q32 (emotions blunted): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency33",
            existing_type=sa.Integer(),
            comment=(
                "Q33 (hear voices): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency34",
            existing_type=sa.Integer(),
            comment=(
                "Q34 (hear voices conversing): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency35",
            existing_type=sa.Integer(),
            comment=(
                "Q35 (neglecting appearance/hygiene): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency36",
            existing_type=sa.Integer(),
            comment=(
                "Q36 (never get things done): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency37",
            existing_type=sa.Integer(),
            comment=(
                "Q37 (few hobbies/interests): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency38",
            existing_type=sa.Integer(),
            comment=(
                "Q38 (feel guilty): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency39",
            existing_type=sa.Integer(),
            comment=(
                "Q39 (feel a failure): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (not a talker): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency40",
            existing_type=sa.Integer(),
            comment=(
                "Q40 (tense): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency41",
            existing_type=sa.Integer(),
            comment=(
                "Q41 (Capgras): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency42",
            existing_type=sa.Integer(),
            comment=(
                "Q42 (see things others cannot): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (magazines/TV personal): frequency? (1 never, 2 sometimes,"
                " 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (some people not what they seem): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (persecuted): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (few/no emotions): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (pessimistic): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("caps", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment="Q1 (sounds loud): distress (1 low - 5 high), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (limbs not own): distress (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (voices commenting): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (feeling a touch): distress (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (hearing words or sentences): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (unexplained tastes): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (sensations flooding): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (sounds distorted): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (hard to distinguish sensations): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (odours strong): distress (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (shapes/people distorted): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (presence of another): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (hypersensitive to touch/temperature): distress (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (tastes stronger than normal): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress22",
            existing_type=sa.Integer(),
            comment=(
                "Q22 (face looks different): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress23",
            existing_type=sa.Integer(),
            comment=(
                "Q23 (lights/colours more intense): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress24",
            existing_type=sa.Integer(),
            comment=(
                "Q24 (feeling of being uplifted): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress25",
            existing_type=sa.Integer(),
            comment=(
                "Q25 (common smells seem different): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress26",
            existing_type=sa.Integer(),
            comment=(
                "Q26 (everyday things look abnormal): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress27",
            existing_type=sa.Integer(),
            comment=(
                "Q27 (altered perception of time): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress28",
            existing_type=sa.Integer(),
            comment=(
                "Q28 (hear voices conversing): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress29",
            existing_type=sa.Integer(),
            comment=(
                "Q29 (smells or odours that others are unaware of): distress"
                " (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (heard thoughts echoed): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress30",
            existing_type=sa.Integer(),
            comment=(
                "Q30 (food/drink tastes unusual): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress31",
            existing_type=sa.Integer(),
            comment=(
                "Q31 (see things that others cannot): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress32",
            existing_type=sa.Integer(),
            comment=(
                "Q32 (hear sounds/music that others cannot): distress (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (see shapes/lights/colours): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (burning or other bodily sensations): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (hear noises/sounds): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (thoughts spoken aloud): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (unexplained smells): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (body changing shape): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse1",
            existing_type=sa.Integer(),
            comment="Q1 (sounds loud): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse10",
            existing_type=sa.Integer(),
            comment="Q10 (limbs not own): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse11",
            existing_type=sa.Integer(),
            comment="Q11 (voices commenting): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse12",
            existing_type=sa.Integer(),
            comment="Q12 (feeling a touch): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (hearing words or sentences): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse14",
            existing_type=sa.Integer(),
            comment="Q14 (unexplained tastes): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse15",
            existing_type=sa.Integer(),
            comment="Q15 (sensations flooding): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse16",
            existing_type=sa.Integer(),
            comment="Q16 (sounds distorted): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (hard to distinguish sensations): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse18",
            existing_type=sa.Integer(),
            comment="Q18 (odours strong): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse19",
            existing_type=sa.Integer(),
            comment="Q19 (shapes/people distorted): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse2",
            existing_type=sa.Integer(),
            comment="Q2 (presence of another): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (hypersensitive to touch/temperature): endorsed? (0 no, 1"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (tastes stronger than normal): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse22",
            existing_type=sa.Integer(),
            comment="Q22 (face looks different): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse23",
            existing_type=sa.Integer(),
            comment=(
                "Q23 (lights/colours more intense): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse24",
            existing_type=sa.Integer(),
            comment="Q24 (feeling of being uplifted): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse25",
            existing_type=sa.Integer(),
            comment=(
                "Q25 (common smells seem different): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse26",
            existing_type=sa.Integer(),
            comment=(
                "Q26 (everyday things look abnormal): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse27",
            existing_type=sa.Integer(),
            comment=(
                "Q27 (altered perception of time): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse28",
            existing_type=sa.Integer(),
            comment="Q28 (hear voices conversing): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse29",
            existing_type=sa.Integer(),
            comment=(
                "Q29 (smells or odours that others are unaware of): endorsed?"
                " (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse3",
            existing_type=sa.Integer(),
            comment="Q3 (heard thoughts echoed): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse30",
            existing_type=sa.Integer(),
            comment="Q30 (food/drink tastes unusual): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse31",
            existing_type=sa.Integer(),
            comment=(
                "Q31 (see things that others cannot): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse32",
            existing_type=sa.Integer(),
            comment=(
                "Q32 (hear sounds/music that others cannot): endorsed? (0 no,"
                " 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse4",
            existing_type=sa.Integer(),
            comment="Q4 (see shapes/lights/colours): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (burning or other bodily sensations): endorsed? (0 no, 1"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse6",
            existing_type=sa.Integer(),
            comment="Q6 (hear noises/sounds): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse7",
            existing_type=sa.Integer(),
            comment="Q7 (thoughts spoken aloud): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse8",
            existing_type=sa.Integer(),
            comment="Q8 (unexplained smells): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse9",
            existing_type=sa.Integer(),
            comment="Q9 (body changing shape): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (sounds loud): frequency (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (limbs not own): frequency (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (voices commenting): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (feeling a touch): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (hearing words or sentences): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (unexplained tastes): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (sensations flooding): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (sounds distorted): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (hard to distinguish sensations): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (odours strong): frequency (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (shapes/people distorted): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (presence of another): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (hypersensitive to touch/temperature): frequency (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (tastes stronger than normal): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency22",
            existing_type=sa.Integer(),
            comment=(
                "Q22 (face looks different): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency23",
            existing_type=sa.Integer(),
            comment=(
                "Q23 (lights/colours more intense): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency24",
            existing_type=sa.Integer(),
            comment=(
                "Q24 (feeling of being uplifted): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency25",
            existing_type=sa.Integer(),
            comment=(
                "Q25 (common smells seem different): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency26",
            existing_type=sa.Integer(),
            comment=(
                "Q26 (everyday things look abnormal): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency27",
            existing_type=sa.Integer(),
            comment=(
                "Q27 (altered perception of time): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency28",
            existing_type=sa.Integer(),
            comment=(
                "Q28 (hear voices conversing): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency29",
            existing_type=sa.Integer(),
            comment=(
                "Q29 (smells or odours that others are unaware of): frequency"
                " (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (heard thoughts echoed): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency30",
            existing_type=sa.Integer(),
            comment=(
                "Q30 (food/drink tastes unusual): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency31",
            existing_type=sa.Integer(),
            comment=(
                "Q31 (see things that others cannot): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency32",
            existing_type=sa.Integer(),
            comment=(
                "Q32 (hear sounds/music that others cannot): frequency (1 low"
                " - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (see shapes/lights/colours): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (burning or other bodily sensations): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (hear noises/sounds): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (thoughts spoken aloud): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (unexplained smells): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (body changing shape): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "intrusiveness1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (sounds loud): intrusiveness (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (limbs not own): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (voices commenting): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (feeling a touch): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (hearing words or sentences): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (unexplained tastes): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (sensations flooding): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (sounds distorted): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (hard to distinguish sensations): intrusiveness (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (odours strong): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (shapes/people distorted): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (presence of another): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (hypersensitive to touch/temperature): intrusiveness (1"
                " low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (tastes stronger than normal): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness22",
            existing_type=sa.Integer(),
            comment=(
                "Q22 (face looks different): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness23",
            existing_type=sa.Integer(),
            comment=(
                "Q23 (lights/colours more intense): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness24",
            existing_type=sa.Integer(),
            comment=(
                "Q24 (feeling of being uplifted): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness25",
            existing_type=sa.Integer(),
            comment=(
                "Q25 (common smells seem different): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness26",
            existing_type=sa.Integer(),
            comment=(
                "Q26 (everyday things look abnormal): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness27",
            existing_type=sa.Integer(),
            comment=(
                "Q27 (altered perception of time): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness28",
            existing_type=sa.Integer(),
            comment=(
                "Q28 (hear voices conversing): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness29",
            existing_type=sa.Integer(),
            comment=(
                "Q29 (smells or odours that others are unaware of):"
                " intrusiveness (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (heard thoughts echoed): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness30",
            existing_type=sa.Integer(),
            comment=(
                "Q30 (food/drink tastes unusual): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness31",
            existing_type=sa.Integer(),
            comment=(
                "Q31 (see things that others cannot): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness32",
            existing_type=sa.Integer(),
            comment=(
                "Q32 (hear sounds/music that others cannot): intrusiveness (1"
                " low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (see shapes/lights/colours): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (burning or other bodily sensations): intrusiveness (1 low"
                " - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (hear noises/sounds): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (thoughts spoken aloud): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (unexplained smells): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (body changing shape): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cardinal_expdet", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aborted",
            existing_type=sa.Integer(),
            comment="Was the task aborted? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_background_intensity",
            existing_type=sa.Float(),
            comment="Auditory background intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_cue_intensity",
            existing_type=sa.Float(),
            comment="Auditory cue intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_target_0_intensity",
            existing_type=sa.Float(),
            comment="Auditory target 0 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_target_1_intensity",
            existing_type=sa.Float(),
            comment="Auditory target 1 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cue_duration_s",
            existing_type=sa.Float(),
            comment="Cue duration (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finished",
            existing_type=sa.Integer(),
            comment="Was the task finished? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "is_detection_response_on_right",
            existing_type=sa.Integer(),
            comment='Is the "detection" response on the right? (0 no, 1 yes)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "isi_duration_s",
            existing_type=sa.Float(),
            comment="Interstimulus interval (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_max_s",
            existing_type=sa.Float(),
            comment="Intertrial interval maximum (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_min_s",
            existing_type=sa.Float(),
            comment="Intertrial interval minimum (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_trial_completed",
            existing_type=sa.Integer(),
            comment="Number of last trial completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "num_blocks",
            existing_type=sa.Integer(),
            comment="Number of blocks",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "pause_every_n_trials",
            existing_type=sa.Integer(),
            comment="Pause every n trials",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stimulus_counterbalancing",
            existing_type=sa.Integer(),
            comment="Stimulus counterbalancing condition",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_background_intensity",
            existing_type=sa.Float(),
            comment="Visual background intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_cue_intensity",
            existing_type=sa.Float(),
            comment="Visual cue intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_target_0_intensity",
            existing_type=sa.Float(),
            comment="Visual target 0 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_target_1_intensity",
            existing_type=sa.Float(),
            comment="Visual target 1 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_target_duration_s",
            existing_type=sa.Float(),
            comment="Visual target duration (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdet_trialgroupspec", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cardinal_expdet_id",
            existing_type=sa.Integer(),
            comment="FK to cardinal_expdet",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "cue",
            existing_type=sa.Integer(),
            comment="Cue number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "group_num",
            existing_type=sa.Integer(),
            comment="Group number (0-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "n_no_target",
            existing_type=sa.Integer(),
            comment="Number of trials with target absent",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_target",
            existing_type=sa.Integer(),
            comment="Number of trials with target present",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_modality",
            existing_type=sa.Integer(),
            comment="Target modality (0 auditory, 1 visual)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_number",
            existing_type=sa.Integer(),
            comment="Target number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdet_trials", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "block",
            existing_type=sa.Integer(),
            comment="Block number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cardinal_expdet_id",
            existing_type=sa.Integer(),
            comment="FK to cardinal_expdet",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "correct",
            existing_type=sa.Integer(),
            comment="Correct side of the middle rating? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cue",
            existing_type=sa.Integer(),
            comment="Cue number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cue_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Cue start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cumulative_points",
            existing_type=sa.Integer(),
            comment="Cumulative points earned",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "detection_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Detection response start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "group_num",
            existing_type=sa.Integer(),
            comment="Group number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "iti_end_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Intertrial interval end time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_length_s",
            existing_type=sa.Float(),
            comment="Intertrial interval (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Intertrial interval start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_end_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Pause end time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_given_before_trial",
            existing_type=sa.Integer(),
            comment="Pause given before trial? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Pause start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "points",
            existing_type=sa.Integer(),
            comment="Points earned this trial",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment="Rating (0 definitely not - 4 definitely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "raw_cue_number",
            existing_type=sa.Integer(),
            comment="Raw cue number (following counterbalancing) (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "responded",
            existing_type=sa.Integer(),
            comment="Responded? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_latency_ms",
            existing_type=sa.Integer(),
            comment="Response latency (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Response time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_modality",
            existing_type=sa.Integer(),
            comment="Target modality (0 auditory, 1 visual)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_number",
            existing_type=sa.Integer(),
            comment="Target number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_present",
            existing_type=sa.Integer(),
            comment="Target present? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Target start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial",
            existing_type=sa.Integer(),
            comment="Trial number (0-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "trial_end_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Trial end time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Trial start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdetthreshold", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "background_filename",
            existing_type=sa.Text(),
            comment="Filename of media used for background",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "background_intensity",
            existing_type=sa.Float(),
            comment="Intensity of background (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finished",
            existing_type=sa.Integer(),
            comment="Subject finished successfully (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "initial_large_intensity_step",
            existing_type=sa.Float(),
            comment="Initial, large, intensity step (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intercept",
            existing_type=sa.Float(),
            comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X))"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_s",
            existing_type=sa.Float(),
            comment="Intertrial interval (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "k",
            existing_type=sa.Float(),
            comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X)); k = slope"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "main_small_intensity_step",
            existing_type=sa.Float(),
            comment="Main, small, intensity step (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "modality",
            existing_type=sa.Integer(),
            comment="Modality (0 auditory, 1 visual)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "num_trials_in_main_sequence",
            existing_type=sa.Integer(),
            comment="Number of trials required in main sequence",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_catch_trial",
            existing_type=sa.Float(),
            comment="Probability of catch trial",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "prompt",
            existing_type=sa.Text(),
            comment="Prompt given to subject",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "slope",
            existing_type=sa.Float(),
            comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X))"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_intensity_max",
            existing_type=sa.Float(),
            comment="Maximum starting intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_intensity_min",
            existing_type=sa.Float(),
            comment="Minimum starting intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_filename",
            existing_type=sa.Text(),
            comment="Filename of media used for target",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_number",
            existing_type=sa.Integer(),
            comment=(
                "Target number (within available targets of that modality)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "theta",
            existing_type=sa.Float(),
            comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X)); theta = -intercept/k ="
                " -intercept/slope"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_target_duration_s",
            existing_type=sa.Float(),
            comment="Visual target duration (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdetthreshold_trials", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cardinal_expdetthreshold_id",
            existing_type=sa.Integer(),
            comment="FK to CardinalExpDetThreshold",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "caught_out_reset",
            existing_type=sa.Integer(),
            comment="Caught out on catch trial, thus reset? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "choice_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Time choice offered (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "intensity",
            existing_type=sa.Float(),
            comment="Target intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "no",
            existing_type=sa.Integer(),
            comment="Subject chose NO? (0 didn't, 1 did)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "responded",
            existing_type=sa.Integer(),
            comment="Responded? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_latency_ms",
            existing_type=sa.Integer(),
            comment="Response latency (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Time of response (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_presented",
            existing_type=sa.Integer(),
            comment="Target presented? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Target presentation time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial",
            existing_type=sa.Integer(),
            comment="Trial number (0-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "trial_ignoring_catch_trials",
            existing_type=sa.Integer(),
            comment="Trial number, ignoring catch trials (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial_num_in_calculation_sequence",
            existing_type=sa.Integer(),
            comment="Trial number as used for threshold calculation",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "yes",
            existing_type=sa.Integer(),
            comment="Subject chose YES? (0 didn't, 1 did)",
            existing_nullable=True,
        )

    with op.batch_alter_table("cbir", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Additional comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "confirm_blanks",
            existing_type=sa.Integer(),
            comment=(
                "Respondent confirmed that blanks are deliberate (N/A) (0/NULL"
                " no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q1, memory: poor day to day memory (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment="Distress Q10, everyday: writing (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q11, everyday: using telephone (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q12, everyday: making hot drink (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress13",
            existing_type=sa.Integer(),
            comment="Distress Q13, everyday: money (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress14",
            existing_type=sa.Integer(),
            comment="Distress Q14, self-care: grooming (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress15",
            existing_type=sa.Integer(),
            comment="Distress Q15, self-care: dressing (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress16",
            existing_type=sa.Integer(),
            comment="Distress Q16, self-care: feeding (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress17",
            existing_type=sa.Integer(),
            comment="Distress Q17, self-care: bathing (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress18",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q18, behaviour: inappropriate humour (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress19",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q19, behaviour: temper outbursts (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q2, memory: asks same questions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress20",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q20, behaviour: uncooperative (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress21",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q21, behaviour: socially embarrassing (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress22",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q22, behaviour: tactless/suggestive (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress23",
            existing_type=sa.Integer(),
            comment="Distress Q23, behaviour: impulsive (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress24",
            existing_type=sa.Integer(),
            comment="Distress Q24, mood: cries (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress25",
            existing_type=sa.Integer(),
            comment="Distress Q25, mood: sad/depressed (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress26",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q26, mood: restless/agitated (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress27",
            existing_type=sa.Integer(),
            comment="Distress Q27, mood: irritable (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress28",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q28, beliefs: visual hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress29",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q29, beliefs: auditory hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment="Distress Q3, memory: loses things (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress30",
            existing_type=sa.Integer(),
            comment="Distress Q30, beliefs: delusions (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress31",
            existing_type=sa.Integer(),
            comment="Distress Q31, eating: sweet tooth (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress32",
            existing_type=sa.Integer(),
            comment="Distress Q32, eating: repetitive (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress33",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q33, eating: increased appetite (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress34",
            existing_type=sa.Integer(),
            comment="Distress Q34, eating: table manners (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress35",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q35, sleep: disturbed at night (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress36",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q36, sleep: daytime sleep increased (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress37",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q37, stereotypy/motor: rigid/fixed opinions (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress38",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q38, stereotypy/motor: routines (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress39",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q39, stereotypy/motor: preoccupied with time (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q4, memory: forgets familiar names (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress40",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q40, stereotypy/motor:  expression/catchphrase (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress41",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q41, motivation: less enthusiasm in usual interests"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress42",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q42, motivation: no interest in new things (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress43",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q43, motivation: fails to contact friends/family"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress44",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q44, motivation: indifferent to family/friend"
                " concerns (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress45",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q45, motivation: reduced affection (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q5, memory: forgets names of objects (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q6, memory: poor concentration (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment="Distress Q7, memory: forgets day (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q8, memory: confused in unusual surroundings (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment=(
                "Distress Q9, everyday: electrical appliances (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency1",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q1, memory: poor day to day memory (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency10",
            existing_type=sa.Integer(),
            comment="Frequency Q10, everyday: writing (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency11",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q11, everyday: using telephone (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency12",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q12, everyday: making hot drink (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency13",
            existing_type=sa.Integer(),
            comment="Frequency Q13, everyday: money (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency14",
            existing_type=sa.Integer(),
            comment="Frequency Q14, self-care: grooming (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency15",
            existing_type=sa.Integer(),
            comment="Frequency Q15, self-care: dressing (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency16",
            existing_type=sa.Integer(),
            comment="Frequency Q16, self-care: feeding (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency17",
            existing_type=sa.Integer(),
            comment="Frequency Q17, self-care: bathing (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency18",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q18, behaviour: inappropriate humour (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency19",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q19, behaviour: temper outbursts (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency2",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q2, memory: asks same questions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency20",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q20, behaviour: uncooperative (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency21",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q21, behaviour: socially embarrassing (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency22",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q22, behaviour: tactless/suggestive (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency23",
            existing_type=sa.Integer(),
            comment="Frequency Q23, behaviour: impulsive (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency24",
            existing_type=sa.Integer(),
            comment="Frequency Q24, mood: cries (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency25",
            existing_type=sa.Integer(),
            comment="Frequency Q25, mood: sad/depressed (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency26",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q26, mood: restless/agitated (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency27",
            existing_type=sa.Integer(),
            comment="Frequency Q27, mood: irritable (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency28",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q28, beliefs: visual hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency29",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q29, beliefs: auditory hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency3",
            existing_type=sa.Integer(),
            comment="Frequency Q3, memory: loses things (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency30",
            existing_type=sa.Integer(),
            comment="Frequency Q30, beliefs: delusions (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency31",
            existing_type=sa.Integer(),
            comment="Frequency Q31, eating: sweet tooth (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency32",
            existing_type=sa.Integer(),
            comment="Frequency Q32, eating: repetitive (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency33",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q33, eating: increased appetite (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency34",
            existing_type=sa.Integer(),
            comment="Frequency Q34, eating: table manners (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency35",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q35, sleep: disturbed at night (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency36",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q36, sleep: daytime sleep increased (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency37",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q37, stereotypy/motor: rigid/fixed opinions (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency38",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q38, stereotypy/motor: routines (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency39",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q39, stereotypy/motor: preoccupied with time (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency4",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q4, memory: forgets familiar names (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency40",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q40, stereotypy/motor:  expression/catchphrase"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency41",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q41, motivation: less enthusiasm in usual interests"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency42",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q42, motivation: no interest in new things (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency43",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q43, motivation: fails to contact friends/family"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency44",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q44, motivation: indifferent to family/friend"
                " concerns (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency45",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q45, motivation: reduced affection (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency5",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q5, memory: forgets names of objects (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency6",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q6, memory: poor concentration (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency7",
            existing_type=sa.Integer(),
            comment="Frequency Q7, memory: forgets day (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency8",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q8, memory: confused in unusual surroundings (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency9",
            existing_type=sa.Integer(),
            comment=(
                "Frequency Q9, everyday: electrical appliances (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cecaq3", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "any_other_comments",
            existing_type=sa.Text(),
            comment="Any other comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_adoptivefather",
            existing_type=sa.Boolean(),
            comment="Raised by, paternal, adoptive father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_birthfather",
            existing_type=sa.Boolean(),
            comment="Raised by, paternal, birth father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_familyfriend",
            existing_type=sa.Boolean(),
            comment="Raised by, paternal, family friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_fosterfather",
            existing_type=sa.Boolean(),
            comment="Raised by, paternal, foster father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_malerelative",
            existing_type=sa.Boolean(),
            comment="Raised by, paternal, male relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_malerelative_detail",
            existing_type=sa.Text(),
            comment="Raised by, paternal, male relative, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_other",
            existing_type=sa.Boolean(),
            comment="Raised by, paternal, other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_other_detail",
            existing_type=sa.Text(),
            comment="Raised by, paternal, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_stepfather",
            existing_type=sa.Boolean(),
            comment="Raised by, paternal, stepfather?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_adoptivemother",
            existing_type=sa.Boolean(),
            comment="Raised by, maternal, adoptive mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_birthmother",
            existing_type=sa.Boolean(),
            comment="Raised by, maternal, birth mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_familyfriend",
            existing_type=sa.Boolean(),
            comment="Raised by, maternal, family friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_femalerelative",
            existing_type=sa.Boolean(),
            comment="Raised by, maternal, female relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_femalerelative_detail",
            existing_type=sa.Text(),
            comment="Raised by, maternal, female relative, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_fostermother",
            existing_type=sa.Boolean(),
            comment="Raised by, maternal, foster mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_other",
            existing_type=sa.Boolean(),
            comment="Raised by, maternal, other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_other_detail",
            existing_type=sa.Text(),
            comment="Raised by, maternal, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_stepmother",
            existing_type=sa.Boolean(),
            comment="Raised by, maternal, stepmother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1b_institution",
            existing_type=sa.Boolean(),
            comment="In institution before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1b_institution_time_years",
            existing_type=sa.Float(),
            comment="In institution, time (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_describe_experience",
            existing_type=sa.Text(),
            comment="Loss of/separation from parent, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_died",
            existing_type=sa.Boolean(),
            comment="Father died before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_died_subject_aged",
            existing_type=sa.Float(),
            comment="Age when father died (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_how_long_first_separation_years",
            existing_type=sa.Float(),
            comment="Paternal separation, how long first separation (y)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_separation_reason",
            existing_type=sa.Integer(),
            comment=(
                "Paternal separation, reason (1 illness, 2 work, 3"
                " divorce/separation, 4 never knew, 5 abandoned, 6 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_first_separated_from_father_aged",
            existing_type=sa.Float(),
            comment="Paternal separation, age (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_first_separated_from_mother_aged",
            existing_type=sa.Float(),
            comment="Maternal separation, age (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_died",
            existing_type=sa.Boolean(),
            comment="Mother died before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_died_subject_aged",
            existing_type=sa.Float(),
            comment="Age when mother died (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_how_long_first_separation_years",
            existing_type=sa.Float(),
            comment="Maternal separation, how long first separation (y)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_separation_reason",
            existing_type=sa.Integer(),
            comment=(
                "Maternal separation, reason (1 illness, 2 work, 3"
                " divorce/separation, 4 never knew, 5 abandoned, 6 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_separated_from_father",
            existing_type=sa.Boolean(),
            comment="Separated from father for >=1y before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_separated_from_mother",
            existing_type=sa.Boolean(),
            comment="Separated from mother for >=1y before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_extra",
            existing_type=sa.Text(),
            comment="Mother figure, extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q1",
            existing_type=sa.Integer(),
            comment="Mother figure, difficult to please (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q10",
            existing_type=sa.Integer(),
            comment="Mother figure, picked on unfairly (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q11",
            existing_type=sa.Integer(),
            comment="Mother figure, there if needed (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q12",
            existing_type=sa.Integer(),
            comment="Mother figure, interested in friends (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q13",
            existing_type=sa.Integer(),
            comment="Mother figure, concerned re whereabouts (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q14",
            existing_type=sa.Integer(),
            comment="Mother figure, cared when ill (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q15",
            existing_type=sa.Integer(),
            comment="Mother figure, neglected basic needs (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q16",
            existing_type=sa.Integer(),
            comment="Mother figure, preferred siblings (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q2",
            existing_type=sa.Integer(),
            comment="Mother figure, concerned re my worries (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q3",
            existing_type=sa.Integer(),
            comment="Mother figure, interested re school (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q4",
            existing_type=sa.Integer(),
            comment="Mother figure, made me feel unwanted (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q5",
            existing_type=sa.Integer(),
            comment="Mother figure, better when upset (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q6",
            existing_type=sa.Integer(),
            comment="Mother figure, critical (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q7",
            existing_type=sa.Integer(),
            comment="Mother figure, unsupervised <10y (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q8",
            existing_type=sa.Integer(),
            comment="Mother figure, time to talk (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q9",
            existing_type=sa.Integer(),
            comment="Mother figure, nuisance (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_which_mother_figure",
            existing_type=sa.Integer(),
            comment=(
                "Mother figure, which one (0 none/skip, 1 birth mother, 2"
                " stepmother, 3 other relative, 4 other non-relative, 5 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_which_mother_figure_other_detail",
            existing_type=sa.Text(),
            comment="Mother figure, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_age_began",
            existing_type=sa.Float(),
            comment="Age these experienced began (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_extra",
            existing_type=sa.Text(),
            comment="Extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q1",
            existing_type=sa.Integer(),
            comment="Mother figure, tease me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q10",
            existing_type=sa.Integer(),
            comment="Mother figure, took things I cherished (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q10_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q11",
            existing_type=sa.Integer(),
            comment="Mother figure, eat disliked until sick (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q11_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q12",
            existing_type=sa.Integer(),
            comment=(
                "Mother figure, deprived light/food/company (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q12_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q13",
            existing_type=sa.Integer(),
            comment="Mother figure, wouldn't let me mix (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q13_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q14",
            existing_type=sa.Integer(),
            comment="Mother figure, obedience through guilt (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q14_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q15",
            existing_type=sa.Integer(),
            comment=(
                "Mother figure, threatened to hurt people dear to me (0 no - 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q15_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q16",
            existing_type=sa.Integer(),
            comment="Mother figure, forced to break law (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q16_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q17",
            existing_type=sa.Integer(),
            comment="Mother figure, said wanted me dead (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q17_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q1_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q2",
            existing_type=sa.Integer(),
            comment="Mother figure, made me keep secrets (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q2_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q3",
            existing_type=sa.Integer(),
            comment="Mother figure, undermined confidence (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q3_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q4",
            existing_type=sa.Integer(),
            comment="Mother figure, contradictory (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q4_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q5",
            existing_type=sa.Integer(),
            comment="Mother figure, played on fears (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q5_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q6",
            existing_type=sa.Integer(),
            comment="Mother figure, liked to see me suffer (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q6_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q7",
            existing_type=sa.Integer(),
            comment="Mother figure, humiliated me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q7_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q8",
            existing_type=sa.Integer(),
            comment="Mother figure, shamed me before others (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q8_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q9",
            existing_type=sa.Integer(),
            comment="Mother figure, rejecting (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q9_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_extra",
            existing_type=sa.Text(),
            comment="Father figure, extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q1",
            existing_type=sa.Integer(),
            comment="Father figure, difficult to please (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q10",
            existing_type=sa.Integer(),
            comment="Father figure, picked on unfairly (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q11",
            existing_type=sa.Integer(),
            comment="Father figure, there if needed (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q12",
            existing_type=sa.Integer(),
            comment="Father figure, interested in friends (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q13",
            existing_type=sa.Integer(),
            comment="Father figure, concerned re whereabouts (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q14",
            existing_type=sa.Integer(),
            comment="Father figure, cared when ill (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q15",
            existing_type=sa.Integer(),
            comment="Father figure, neglected basic needs (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q16",
            existing_type=sa.Integer(),
            comment="Father figure, preferred siblings (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q2",
            existing_type=sa.Integer(),
            comment="Father figure, concerned re my worries (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q3",
            existing_type=sa.Integer(),
            comment="Father figure, interested re school (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q4",
            existing_type=sa.Integer(),
            comment="Father figure, made me feel unwanted (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q5",
            existing_type=sa.Integer(),
            comment="Father figure, better when upset (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q6",
            existing_type=sa.Integer(),
            comment="Father figure, critical (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q7",
            existing_type=sa.Integer(),
            comment="Father figure, unsupervised <10y (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q8",
            existing_type=sa.Integer(),
            comment="Father figure, time to talk (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q9",
            existing_type=sa.Integer(),
            comment="Father figure, nuisance (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_which_father_figure",
            existing_type=sa.Integer(),
            comment=(
                "Father figure, which one (0 none/skip, 1 birth father, 2"
                " stepfather, 3 other relative, 4 other non-relative, 5 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_which_father_figure_other_detail",
            existing_type=sa.Text(),
            comment="Father figure, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_age_began",
            existing_type=sa.Float(),
            comment="Age these experienced began (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_extra",
            existing_type=sa.Text(),
            comment="Extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q1",
            existing_type=sa.Integer(),
            comment="Father figure, tease me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q10",
            existing_type=sa.Integer(),
            comment="Father figure, took things I cherished (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q10_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q11",
            existing_type=sa.Integer(),
            comment="Father figure, eat disliked until sick (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q11_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q12",
            existing_type=sa.Integer(),
            comment=(
                "Father figure, deprived light/food/company (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q12_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q13",
            existing_type=sa.Integer(),
            comment="Father figure, wouldn't let me mix (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q13_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q14",
            existing_type=sa.Integer(),
            comment="Father figure, obedience through guilt (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q14_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q15",
            existing_type=sa.Integer(),
            comment=(
                "Father figure, threatened to hurt people dear to me (0 no - 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q15_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q16",
            existing_type=sa.Integer(),
            comment="Father figure, forced to break law (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q16_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q17",
            existing_type=sa.Integer(),
            comment="Father figure, said wanted me dead (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q17_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q1_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q2",
            existing_type=sa.Integer(),
            comment="Father figure, made me keep secrets (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q2_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q3",
            existing_type=sa.Integer(),
            comment="Father figure, undermined confidence (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q3_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q4",
            existing_type=sa.Integer(),
            comment="Father figure, contradictory (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q4_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q5",
            existing_type=sa.Integer(),
            comment="Father figure, played on fears (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q5_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q6",
            existing_type=sa.Integer(),
            comment="Father figure, liked to see me suffer (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q6_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q7",
            existing_type=sa.Integer(),
            comment="Father figure, humiliated me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q7_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q8",
            existing_type=sa.Integer(),
            comment="Father figure, shamed me before others (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q8_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q9",
            existing_type=sa.Integer(),
            comment="Father figure, rejecting (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q9_frequency",
            existing_type=sa.Integer(),
            comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_parent_mental_problem",
            existing_type=sa.Integer(),
            comment=(
                "Parent/s had emotional/mental health problems (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_parent_physical_problem",
            existing_type=sa.Integer(),
            comment="Parent/s had disability/physical illness (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q1",
            existing_type=sa.Integer(),
            comment="Responsibility (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q10",
            existing_type=sa.Integer(),
            comment="Parents confided their problems (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q11",
            existing_type=sa.Integer(),
            comment=(
                "Parents relied on you for emotional support (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q12",
            existing_type=sa.Integer(),
            comment="Parents cried in front of you (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q13",
            existing_type=sa.Integer(),
            comment="Concerned/worried re parent (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q14",
            existing_type=sa.Integer(),
            comment="Tried to support/care for parent (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q15",
            existing_type=sa.Integer(),
            comment="Try to make parent smile when upset (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q16",
            existing_type=sa.Integer(),
            comment=(
                "Parents made you feel guilty for their sacrifices (1 no - 5"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q17",
            existing_type=sa.Integer(),
            comment="Had to keep secrets for parent (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q2",
            existing_type=sa.Integer(),
            comment="Housework (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q3",
            existing_type=sa.Integer(),
            comment="Look after young siblings (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q4",
            existing_type=sa.Integer(),
            comment="Cooking/cleaning (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q5",
            existing_type=sa.Integer(),
            comment="Miss school for domestic responsibilities (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q6",
            existing_type=sa.Integer(),
            comment=(
                "Miss seeing friends for domestic responsibilities (1 no - 5"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q7",
            existing_type=sa.Integer(),
            comment="Parents said they couldn't cope (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q8",
            existing_type=sa.Integer(),
            comment="Parents looked to you for help (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q9",
            existing_type=sa.Integer(),
            comment="Parents coped if you were hurt/ill (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_which_parent_cared_for",
            existing_type=sa.Integer(),
            comment=(
                "Which parent did you have to provide care for (0 none, 1"
                " mother, 2 father, 3 both, 4 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant",
            existing_type=sa.Boolean(),
            comment="Adult confidant?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_additional",
            existing_type=sa.Text(),
            comment="Adult confidant, additional notes",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_familyfriend",
            existing_type=sa.Boolean(),
            comment="Adult confidant, family friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_father",
            existing_type=sa.Boolean(),
            comment="Adult confidant, father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_mother",
            existing_type=sa.Boolean(),
            comment="Adult confidant, mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_other",
            existing_type=sa.Boolean(),
            comment="Adult confidant, other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_other_detail",
            existing_type=sa.Text(),
            comment="Adult confidant, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_otherrelative",
            existing_type=sa.Boolean(),
            comment="Adult confidant, other relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_responsibleadult",
            existing_type=sa.Boolean(),
            comment="Adult confidant, teacher/vicar/etc.?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant",
            existing_type=sa.Boolean(),
            comment="Child confidant?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_additional",
            existing_type=sa.Text(),
            comment="Child confidant, additional notes",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_brother",
            existing_type=sa.Boolean(),
            comment="Child confidant, brother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_closefriend",
            existing_type=sa.Boolean(),
            comment="Child confidant, close friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_other",
            existing_type=sa.Boolean(),
            comment="Child confidant, other person?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_other_detail",
            existing_type=sa.Text(),
            comment="Child confidant, other person, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_otherfriend",
            existing_type=sa.Boolean(),
            comment="Child confidant, other less close friend(s)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_otherrelative",
            existing_type=sa.Boolean(),
            comment="Child confidant, other relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_sister",
            existing_type=sa.Boolean(),
            comment="Child confidant, sister?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_additional",
            existing_type=sa.Text(),
            comment="Two closest people include: additional notes",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_adultfriend",
            existing_type=sa.Boolean(),
            comment="Two closest people include: adult family friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_childfriend",
            existing_type=sa.Boolean(),
            comment="Two closest people include: friend your age?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_father",
            existing_type=sa.Boolean(),
            comment="Two closest people include: father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_mother",
            existing_type=sa.Boolean(),
            comment="Two closest people include: mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_other",
            existing_type=sa.Boolean(),
            comment="Two closest people include: other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_other_detail",
            existing_type=sa.Text(),
            comment="Two closest people include: other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_otherrelative",
            existing_type=sa.Boolean(),
            comment="Two closest people include: other relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_sibling",
            existing_type=sa.Boolean(),
            comment="Two closest people include: sibling?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_abuse_by_nonparent",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by anyone else in household?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_abused_by_father",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_abused_by_mother",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_abuse_age_began",
            existing_type=sa.Float(),
            comment="Physical abuse, by father, age began (y)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_hit_how",
            existing_type=sa.Integer(),
            comment=(
                "Physical abuse, by father, hit how (1 belt/stick, 2"
                " punched/kicked, 3 hit with hand, 4 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_hit_more_than_once",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by father, hit on >1 occasion",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_injured",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by father, injured?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_out_of_control",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by father, out of control?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_abuse_age_began",
            existing_type=sa.Float(),
            comment="Physical abuse, by mother, age began (y)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_hit_how",
            existing_type=sa.Integer(),
            comment=(
                "Physical abuse, by mother, hit how (1 belt/stick, 2"
                " punched/kicked, 3 hit with hand, 4 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_hit_more_than_once",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by mother, hit on >1 occasion",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_injured",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by mother, injured?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_out_of_control",
            existing_type=sa.Boolean(),
            comment="Physical abuse, by mother, out of control?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_nonparent_abuse_description",
            existing_type=sa.Text(),
            comment="Physical abuse, nonparent, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_parental_abuse_description",
            existing_type=sa.Text(),
            comment="Physical abuse, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_physicalabuse",
            existing_type=sa.Boolean(),
            comment="Physical abuse?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_any_unwanted_sexual_experience",
            existing_type=sa.Integer(),
            comment="Any unwanted sexual experiences (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_age",
            existing_type=sa.Float(),
            comment="Sexual abuse, first experience, age it began",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_in_household",
            existing_type=sa.Boolean(),
            comment=(
                "Sexual abuse, first experience, person lived in household?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_intercourse",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, first experience, sexual intercourse?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_more_than_once",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, first experience, happened more than once?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_person_known",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, first experience, knew the person?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_relative",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, first experience, person was a relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_touch_privates_other",
            existing_type=sa.Boolean(),
            comment=(
                "Sexual abuse, first experience, touched their private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_touch_privates_subject",
            existing_type=sa.Boolean(),
            comment=(
                "Sexual abuse, first experience, touched your private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_age",
            existing_type=sa.Float(),
            comment="Sexual abuse, other experience, age it began",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_in_household",
            existing_type=sa.Boolean(),
            comment=(
                "Sexual abuse, other experience, person lived in household?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_intercourse",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, other experience, sexual intercourse?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_more_than_once",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, other experience, happened more than once?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_person_known",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, other experience, knew the person?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_relative",
            existing_type=sa.Boolean(),
            comment="Sexual abuse, other experience, person was a relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_touch_privates_other",
            existing_type=sa.Boolean(),
            comment=(
                "Sexual abuse, other experience, touched their private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_touch_privates_subject",
            existing_type=sa.Boolean(),
            comment=(
                "Sexual abuse, other experience, touched your private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_unwanted_intercourse",
            existing_type=sa.Integer(),
            comment="Unwanted intercourse before 17yo (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_unwanted_sexual_description",
            existing_type=sa.Text(),
            comment="Sexual abuse, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_upsetting_sexual_adult_authority",
            existing_type=sa.Integer(),
            comment=(
                "Upsetting sexual experiences under 17yo with related adult or"
                " someone in authority (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cesd", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (sensitivity/irritability) (0 rarely/none of the time - 4"
                " all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (fearful) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (sleep restless) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (happy) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (uncommunicative) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (lonely) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (perceived unfriendliness) (0 rarely/none of the time - 4"
                " all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (enjoyment) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (crying spells) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (sadness) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (feeling disliked) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (poor appetite) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (could not get going) (0 rarely/none of the time - 4 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (unshakeable blues) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (low self-esteem) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (poor concentration) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (depressed) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (everything effortful) (0 rarely/none of the time - 4 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (hopeful) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (feelings of failure) (0 rarely/none of the time - 4 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cesdr", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (poor appetite) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (loss of interest) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (oversleeping) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (moving slowly) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (fidgety) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (wished were dead) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (wanted to hurt self) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (tiredness) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (disliked self) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (unintended weight loss) (0 not at all - 4 nearly every"
                " day for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (difficulty getting to sleep) (0 not at all - 4 nearly"
                " every day for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (unshakable blues) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (lack of focus) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (poor concentration) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (depressed) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (sleep restless) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (sad) (0 not at all - 4 nearly every day for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (could not get going) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (nothing made me happy) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (felt a bad person) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cgi", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1. Severity (1-7, higher worse, 0 not assessed)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2. Global improvement (1-7, higher worse, 0 not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (calculated). Efficacy index [(Q3T - 1) * 4 + Q3S].",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3s",
            existing_type=sa.Integer(),
            comment="Q3S. Side effects (1-4, higher worse, 0 not assessed)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3t",
            existing_type=sa.Integer(),
            comment=(
                "Q3T. Therapeutic effects (1-4, higher worse, 0 not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cgi_i", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q",
            existing_type=sa.Integer(),
            comment="Global improvement (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cgisch", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change1",
            existing_type=sa.Integer(),
            comment="Change Q1, positive (1-7, higher worse, or 9 N/A)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change2",
            existing_type=sa.Integer(),
            comment="Change Q2, negative (1-7, higher worse, or 9 N/A)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change3",
            existing_type=sa.Integer(),
            comment="Change Q3, depressive (1-7, higher worse, or 9 N/A)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change4",
            existing_type=sa.Integer(),
            comment="Change Q4, cognitive (1-7, higher worse, or 9 N/A)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change5",
            existing_type=sa.Integer(),
            comment="Change Q5, overall (1-7, higher worse, or 9 N/A)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "severity1",
            existing_type=sa.Integer(),
            comment="Severity Q1, positive (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity2",
            existing_type=sa.Integer(),
            comment="Severity Q2, negative (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity3",
            existing_type=sa.Integer(),
            comment="Severity Q3, depressive (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity4",
            existing_type=sa.Integer(),
            comment="Severity Q4, cognitive (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity5",
            existing_type=sa.Integer(),
            comment="Severity Q5, overall (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cisr", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx2",
            existing_type=sa.Integer(),
            comment=(
                "Anxiety/nervousness/tension: how many days in past week (1:"
                " none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx3",
            existing_type=sa.Integer(),
            comment=(
                "Anxiety/nervousness/tension: how unpleasant in past week (1"
                " not at all, 2 a little unpleasant, 3 unpleasant, 4 very"
                " unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx4",
            existing_type=sa.Integer(),
            comment=(
                "Anxiety/nervousness/tension: physical symptoms in past week?"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx5",
            existing_type=sa.Integer(),
            comment=(
                "Anxiety/nervousness/tension: for >3h on any day in past week?"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_dur",
            existing_type=sa.Integer(),
            comment=(
                "Anxiety/nervousness/tension: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_mand1",
            existing_type=sa.Integer(),
            comment="Anxious/nervous in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_mand2",
            existing_type=sa.Integer(),
            comment=(
                "Muscle tension/couldn't relax in past month? (1 no, 2"
                " sometimes, 3 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_phobia1",
            existing_type=sa.Integer(),
            comment="Phobic anxiety in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_phobia2",
            existing_type=sa.Integer(),
            comment=(
                "Phobic anxiety: always specific? (1 always specific, 2"
                " sometimes general)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "appetite1",
            existing_type=sa.Integer(),
            comment="Marked appetite loss in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "appetite2",
            existing_type=sa.Integer(),
            comment="Marked increase in appetite in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp1",
            existing_type=sa.Integer(),
            comment=(
                "Compulsions: how many days in past week (1: none, 2: one to"
                " three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp2",
            existing_type=sa.Integer(),
            comment="Compulsions: tried to stop in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp3",
            existing_type=sa.Integer(),
            comment=(
                "Compulsions: upsetting/annoying in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp4",
            existing_type=sa.Integer(),
            comment=(
                "Compulsions: greatest number of repeats in past week (1:"
                " once, i.e. two times altogether; 2: two repeats; 3: three or"
                " more repeats)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp_dur",
            existing_type=sa.Integer(),
            comment=(
                "Compulsions: for how long? (1: <2 weeks; 2: 2 weeks–6 months;"
                " 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp_mand1",
            existing_type=sa.Integer(),
            comment="Compulsions in past month (1 no, 2 sometimes, 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc1",
            existing_type=sa.Integer(),
            comment=(
                "Concentration/memory problems: days in past week (1: none, 2:"
                " one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc2",
            existing_type=sa.Integer(),
            comment=(
                "In past week, could concentrate on all of: TV, newspaper,"
                " conversation (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc3",
            existing_type=sa.Integer(),
            comment=(
                "Problems with concentration have stopped you from getting on"
                " with things in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc4",
            existing_type=sa.Integer(),
            comment="Forgotten anything important in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc_dur",
            existing_type=sa.Integer(),
            comment=(
                "Problems with concentration: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc_mand1",
            existing_type=sa.Integer(),
            comment=(
                "Problems in concentrating during past monnth? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc_mand2",
            existing_type=sa.Integer(),
            comment=(
                "Problems with forgetting things during past month? (1 no, 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr1",
            existing_type=sa.Integer(),
            comment="Sad/miserable/depressed in past week? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr2",
            existing_type=sa.Integer(),
            comment=(
                "In the past week, able to enjoy/take an interest in things as"
                " much as usual? (1 yes; 2 no, less enjoyment than usual; 3"
                " no, don't enjoy anything)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr3",
            existing_type=sa.Integer(),
            comment=(
                "[Depressed mood] or [anhedonia] on how many days in past week"
                " (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr4",
            existing_type=sa.Integer(),
            comment=(
                "[Depressed mood] or [anhedonia] for >3h on any day in past"
                " week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr5",
            existing_type=sa.Integer(),
            comment=(
                "In past week, during [depressed mood] or [anhedonia], did"
                " nice things/company make you happier? (1 always, 2"
                " sometimes, 3 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_content",
            existing_type=sa.Integer(),
            comment=(
                "Main reason for [depressed mood] or [anhedonia]? (1 family"
                " members; 2 relationships with friends/colleagues; 3 housing;"
                " 4 money/bills; 5 own physical health; 6 own mental health; 7"
                " work/lack of work; 8 legal; 9 political/news)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_dur",
            existing_type=sa.Integer(),
            comment=(
                "Depressed mood/anhedonia: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_mand1",
            existing_type=sa.Integer(),
            comment="Sad/miserable/depressed in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_mand2",
            existing_type=sa.Integer(),
            comment=(
                "In the past month, able to enjoy/take an interest in things"
                " as much as usual? (1 yes; 2 no, less enjoyment than usual; 3"
                " no, don't enjoy anything)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth1",
            existing_type=sa.Integer(),
            comment=(
                "Diurnal mood variation in past week (1 worse in the morning,"
                " 2 worse in the evening, 3 varies, 4 no difference)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth10",
            existing_type=sa.Integer(),
            comment="Thoughts of way to kill self in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth2",
            existing_type=sa.Integer(),
            comment=(
                "Libido in past month (1 not applicable, 2 no change, 3"
                " increased, 4 decreased)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth3",
            existing_type=sa.Integer(),
            comment="Restlessness in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth4",
            existing_type=sa.Integer(),
            comment="Psychomotor retardation in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth5",
            existing_type=sa.Integer(),
            comment=(
                "Guilt/blamed self in past week (1 never, 2 only when it was"
                " my fault, 3 sometimes, 4 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth6",
            existing_type=sa.Integer(),
            comment=(
                "Feeling not as good as other people in past week (1 no, 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth7",
            existing_type=sa.Integer(),
            comment="Hopeless in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth8",
            existing_type=sa.Integer(),
            comment=(
                "Life not worth living in past week (1 no, 2 sometimes, 3"
                " always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth9",
            existing_type=sa.Integer(),
            comment=(
                "Thoughts of suicide in past week (1 no; 2 yes, but would"
                " never commit suicide; 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "disable",
            existing_type=sa.Integer(),
            comment="Longstanding illness/disability/infirmity (1 yes, 2 no)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "doctor",
            existing_type=sa.Integer(),
            comment=(
                "Have you spoken to your doctor about these thoughts of"
                " killing yourself (1 yes; 2 no, but have talked to other"
                " people; 3 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "empstat",
            existing_type=sa.Integer(),
            comment=(
                "(Demographics) Current employment status (1 working full"
                " time, 2 working part time, 3 student, 4 retired, 5"
                " houseperson, 6 unemployed job seeker, 7 unemployed due to"
                " ill health,8 prefer not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "emptype",
            existing_type=sa.Integer(),
            comment=(
                "(Demographics) Current/last paid employment (1 self-employed"
                " with paid employees, 2 self-employed with no paid employees,"
                " 3 employee, 4 foreman/supervisor, 5 manager, 6 not"
                " applicable,7 prefer not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnic",
            existing_type=sa.Integer(),
            comment=(
                "(Demographics) Ethnicity (1 white, 2 mixed, 3 Asian/British"
                " Asian, 4 Black/Black British, 5 Chinese, 6 other, 7 prefer"
                " not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_cause1",
            existing_type=sa.Integer(),
            comment=(
                "Main reason for feeling tired (1 problems with sleep; 2"
                " medication; 3 physical illness; 4 working too hard inc."
                " childcare; 5 stress/worry/other psychological; 6 physical"
                " exercise; 7 other; 8 don't know)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_cause2",
            existing_type=sa.Integer(),
            comment=(
                "Main reason for lacking energy (1 problems with sleep; 2"
                " medication; 3 physical illness; 4 working too hard inc."
                " childcare; 5 stress/worry/other psychological; 6 physical"
                " exercise; 7 other; 8 don't know)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_dur",
            existing_type=sa.Integer(),
            comment=(
                "Feeling tired/lacking energy for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy1",
            existing_type=sa.Integer(),
            comment=(
                "Lacking energy: days in past week (1: none, 2: one to three,"
                " 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy2",
            existing_type=sa.Integer(),
            comment=(
                "Lacking energy: for >3h on any one day in past week (1 no, 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy3",
            existing_type=sa.Integer(),
            comment=(
                "So lacking in energy you've had to push yourself to get"
                " things done in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy4",
            existing_type=sa.Integer(),
            comment=(
                "Lacking energy during an enjoyable activity (1 no, 2 yes, 3"
                " haven't done anything enjoyable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_mand1",
            existing_type=sa.Integer(),
            comment="Tired in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_mand2",
            existing_type=sa.Integer(),
            comment="Lacking in energy in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired1",
            existing_type=sa.Integer(),
            comment=(
                "Tired: days in past week (1: none, 2: one to three, 3: four"
                " or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired2",
            existing_type=sa.Integer(),
            comment="Tired: >3h on any one day in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired3",
            existing_type=sa.Integer(),
            comment=(
                "So tired you've had to push yourself to get things done in"
                " past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired4",
            existing_type=sa.Integer(),
            comment=(
                "Tired during an enjoyable activity (1 no, 2 yes, 3 haven't"
                " done anything enjoyable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "forget_dur",
            existing_type=sa.Integer(),
            comment=(
                "Problems with memory: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gp_year",
            existing_type=sa.Integer(),
            comment=(
                "Consultations with GP in past year (0: none, 1: 1–2, 2: 3–4,"
                " 3: 6–10; 4: >10"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "home",
            existing_type=sa.Integer(),
            comment=(
                "(Demographics) Housing situation (1 home owner, 2 tenant, 3"
                " living with relative/friend, 4 hostel/care home, 5 homeless,"
                " 6 other,7 prefer not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo1",
            existing_type=sa.Integer(),
            comment=(
                "Worrying about health/having a serious illness: how many days"
                " in past week? (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo2",
            existing_type=sa.Integer(),
            comment="Worrying too much about physical health? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo3",
            existing_type=sa.Integer(),
            comment=(
                "Worrying about health: how unpleasant? (1 not at all, 2 a"
                " little unpleasant, 3 unpleasant, 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo4",
            existing_type=sa.Integer(),
            comment=(
                "Able to take mind off health worries in past week? (1 yes,"
                " 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo_dur",
            existing_type=sa.Integer(),
            comment=(
                "Worrying about physical health: for how long? (1: <2 weeks;"
                " 2: 2 weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo_mand1",
            existing_type=sa.Integer(),
            comment=(
                "Worried about physical health in past month? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo_mand2",
            existing_type=sa.Integer(),
            comment="Do you worry you have a serious illness? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "illness",
            existing_type=sa.Integer(),
            comment=(
                "Conditions (1 diabetes, 2 asthma, 3 arthritis, 4 heart"
                " disease, 5 high blood pressure, 6 lung disease, 7 more than"
                " one of the above, 8 none of the above)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit1",
            existing_type=sa.Integer(),
            comment=(
                "Irritable/short-tempered/angry: days in past week (1: none,"
                " 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit2",
            existing_type=sa.Integer(),
            comment=(
                "Irritable/short-tempered/angry: for >1h on any day in past"
                " week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit3",
            existing_type=sa.Integer(),
            comment=(
                "Irritable/short-tempered/angry: wanted to shout at someone?"
                " (1 no; yes but didn't shout; 3 yes and did shout)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit4",
            existing_type=sa.Integer(),
            comment=(
                "In past week, have you had arguments/rows/lost temper? (1 no;"
                " 2 yes but justified; 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit_dur",
            existing_type=sa.Integer(),
            comment=(
                "Irritable/short-tempered/angry: for how long? (1: <2 weeks;"
                " 2: 2 weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit_mand1",
            existing_type=sa.Integer(),
            comment=(
                "Irritable with those around you in past month? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit_mand2",
            existing_type=sa.Integer(),
            comment=(
                "Short-tempered/angry over trivial things in past month? (1"
                " no, 2 sometimes, 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "married",
            existing_type=sa.Integer(),
            comment=(
                "(Demographics) Marital status (1 married/living as married, 2"
                " single, 3 separated, 4 divorced, 5 widowed, 6 prefer not to"
                " say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess1",
            existing_type=sa.Integer(),
            comment=(
                "Obsessions: how many days in past week (1: none, 2: one to"
                " three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess2",
            existing_type=sa.Integer(),
            comment="Obsessions: tried to stop in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess3",
            existing_type=sa.Integer(),
            comment=(
                "Obsessions: upsetting/annoying in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess4",
            existing_type=sa.Integer(),
            comment=(
                "Obsessions: longest time spent thinking these thoughts, in"
                " past week (1: <15min; 2: >=15min)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess_dur",
            existing_type=sa.Integer(),
            comment=(
                "Obsessions: for how long? (1: <2 weeks; 2: 2 weeks–6 months;"
                " 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess_mand1",
            existing_type=sa.Integer(),
            comment="Obsessions in past month (1 no, 2 sometimes, 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess_mand2",
            existing_type=sa.Integer(),
            comment=(
                "Obsessions: same thoughts repeating or general worries (1"
                " same thoughts over and over, 2 worrying about something in"
                " general)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "overall2",
            existing_type=sa.Integer(),
            comment=(
                "Overall impact on normal activities in past week (1 not at"
                " all; 2 they have made things more difficult but I get"
                " everything done; 3 they have stopped one activity; 4 they"
                " have stopped >1 activity)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic1",
            existing_type=sa.Integer(),
            comment=(
                "Panic: how often in past week (1 not in past seven days, 2"
                " once, 3 more than once)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic2",
            existing_type=sa.Integer(),
            comment=(
                "Panic: how unpleasant in past week (1 a little uncomfortable;"
                " 2 unpleasant; 3 unbearable, or very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic3",
            existing_type=sa.Integer(),
            comment=(
                "Panic: in the past week, did the worst panic last >10min (1:"
                " <10min; 2 >=10min)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic4",
            existing_type=sa.Integer(),
            comment="Do panics start suddenly? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic5",
            existing_type=sa.Integer(),
            comment=(
                "Is panic always brought on by specific things? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic_dur",
            existing_type=sa.Integer(),
            comment=(
                "Panic: for how long? (1: <2 weeks; 2: 2 weeks–6 months; 3: 6"
                " months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic_mand",
            existing_type=sa.Integer(),
            comment=(
                "Panic in past month (1: no, my anxiety never got that bad; 2:"
                " yes, sometimes; 3: yes, often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_a",
            existing_type=sa.Integer(),
            comment="Panic symptom in past week: heart racing (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_b",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: hands sweaty/clammy (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_c",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: trembling/shaking (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_d",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: short of breath (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_e",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: choking sensation (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_f",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: chest pain/pressure/discomfort (1"
                " no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_g",
            existing_type=sa.Integer(),
            comment="Panic symptom in past week: nausea (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_h",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: dizzy/unsteady/lightheaded/faint"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_i",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: derealization/depersonalization"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_j",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: losing control/going crazy (1 no,"
                " 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_k",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: fear were dying (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_l",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: tingling/numbness (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_m",
            existing_type=sa.Integer(),
            comment=(
                "Panic symptom in past week: hot flushes/chills (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "phobias1",
            existing_type=sa.Integer(),
            comment=(
                "Phobic anxiety: days in past week (1: none, 2: one to three,"
                " 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias2",
            existing_type=sa.Integer(),
            comment=(
                "Phobic anxiety: physical symptoms in past week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias3",
            existing_type=sa.Integer(),
            comment="Phobic avoidance in past week? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias4",
            existing_type=sa.Integer(),
            comment=(
                "Phobic avoidance: how many times in past week? (1: none, 2:"
                " 1–3, 3: >=4)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias_dur",
            existing_type=sa.Integer(),
            comment=(
                "Phobic anxiety: for how long? (1: <2 weeks; 2: 2 weeks–6"
                " months; 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias_mand",
            existing_type=sa.Integer(),
            comment="Phobic avoidance in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias_type1",
            existing_type=sa.Integer(),
            comment=(
                "Which phobia? (1 travelling alone by bus/train; 2 being far"
                " from home; 3 public eating/speaking; 4 sight of blood; 5"
                " crowded shops; 6 insects/spiders/animals; 7 being watched; 8"
                " enclosed spaces or heights; 9 something else)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_cause",
            existing_type=sa.Integer(),
            comment=(
                "What are your sleep difficulties caused by? (1 noise, 2 shift"
                " work, 3 pain/illness, 4 worries, 5 unknown, 6 other"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_dur",
            existing_type=sa.Integer(),
            comment=(
                "How long have you had these problems with sleep? (1: <2"
                " weeks; 2: 2 weeks–6 months; 3: 6 months–1 year; 4: 1–2"
                " years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_emw",
            existing_type=sa.Integer(),
            comment=(
                "Woken >2h earlier (and couldn't return to sleep) in past"
                " week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_gain1",
            existing_type=sa.Integer(),
            comment=(
                "Sleep gain: how many nights in past week (1: none, 2: one to"
                " three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_gain2",
            existing_type=sa.Integer(),
            comment=(
                "On night with most sleep in past week, how much more than"
                " usual? (1: <15min, 2: 15–60min, 3: 1–3h, 4: >=3h)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_gain3",
            existing_type=sa.Integer(),
            comment=(
                "On how many nights in past week did you sleep >3h longer than"
                " usual? (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_lose1",
            existing_type=sa.Integer(),
            comment=(
                "Sleep loss: nights in past week with problems (1: none, 2:"
                " one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_lose2",
            existing_type=sa.Integer(),
            comment=(
                "On night with least sleep in past week, how long trying to"
                " get to sleep? (1: <15min, 2: 15–60min, 3: 1–3h, 4: >=3h)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_lose3",
            existing_type=sa.Integer(),
            comment=(
                "On how many nights in past week did you spend >=3h trying to"
                " get to sleep? (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_mand1",
            existing_type=sa.Integer(),
            comment="Problems with sleep loss in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_mand2",
            existing_type=sa.Integer(),
            comment=(
                "Problems with excess sleep in past month (1 no, 2 slept more"
                " than usual but not a problem, 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis1",
            existing_type=sa.Integer(),
            comment=(
                "Discomfort brought on or made worse because"
                " low/anxious/stressed (1 never, 2 sometimes, 3 always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis2",
            existing_type=sa.Integer(),
            comment=(
                "Discomfort: days in past week (1: none, 2: one to three, 3:"
                " four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis3",
            existing_type=sa.Integer(),
            comment=(
                "Discomfort: lasted >3h on any day in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis4",
            existing_type=sa.Integer(),
            comment=(
                "Discomfort: unpleasant in past week? (1 not at all, 2 a"
                " little unpleasant, 3 unpleasant, 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis5",
            existing_type=sa.Integer(),
            comment=(
                "Discomfort: bothersome whilst doing something interesting in"
                " past week? (1 no, 2 yes, 3 haven't done anything"
                " interesting)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dur",
            existing_type=sa.Integer(),
            comment=(
                "Duration of ache/pain/discomfort (1: <2 weeks; 2: 2 weeks–6"
                " months; 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_mand1",
            existing_type=sa.Integer(),
            comment="Any aches/pains in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_mand2",
            existing_type=sa.Integer(),
            comment="Bodily discomfort in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain1",
            existing_type=sa.Integer(),
            comment=(
                "Pain/ache brought on or made worse because"
                " low/anxious/stressed (1 never, 2 sometimes, 3 always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain2",
            existing_type=sa.Integer(),
            comment=(
                "Pain: days in past week (1: none, 2: one to three, 3: four or"
                " more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain3",
            existing_type=sa.Integer(),
            comment="Pain: lasted >3h on any day in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain4",
            existing_type=sa.Integer(),
            comment=(
                "Pain: unpleasant in past week? (1 not at all, 2 a little"
                " unpleasant, 3 unpleasant, 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain5",
            existing_type=sa.Integer(),
            comment=(
                "Pain: bothersome whilst doing something interesting in past"
                " week? (1 no, 2 yes, 3 haven't done anything interesting)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight1",
            existing_type=sa.Integer(),
            comment="Weight loss in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight2",
            existing_type=sa.Integer(),
            comment="Weight loss: trying to lose weight? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight3",
            existing_type=sa.Integer(),
            comment="Weight loss amount (1: ≥0.5 stones; 2: <0.5 stones)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight4",
            existing_type=sa.Integer(),
            comment=(
                "Weight gain in past month (1 yes, 2 no, 3 yes but pregnant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight5",
            existing_type=sa.Integer(),
            comment="Weight gain amount (1: ≥0.5 stones; 2: <0.5 stones)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry2",
            existing_type=sa.Integer(),
            comment=(
                "Worries (about things other than physical health) on how many"
                " days in past week (1: none, 2: one to three, 3: four or"
                " more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry3",
            existing_type=sa.Integer(),
            comment="Worrying too much? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry4",
            existing_type=sa.Integer(),
            comment=(
                "How unpleasant is worry (about things other than physical"
                " health) (1 not at all, 2 a little unpleasant, 3 unpleasant,"
                " 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry5",
            existing_type=sa.Integer(),
            comment=(
                "Worry (about things other than physical health) for >3h on"
                " any day in past week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry_cont1",
            existing_type=sa.Integer(),
            comment=(
                "Main source of worry in past week? (1 family members; 2"
                " relationships with friends/colleagues; 3 housing; 4"
                " money/bills; 5 own physical health; 6 own mental health; 7"
                " work/lack of work; 8 legal; 9 political/news)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry_dur",
            existing_type=sa.Integer(),
            comment=(
                "Worry (about things other than physical health): for how"
                " long? (1: <2 weeks; 2: 2 weeks–6 months; 3: 6 months–1 year;"
                " 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry_mand1",
            existing_type=sa.Integer(),
            comment=(
                "Excessive worry in past month? (1 no, 2 sometimes, 3 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry_mand2",
            existing_type=sa.Integer(),
            comment="Any worries at all in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )

    with op.batch_alter_table("ciwa", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dbp",
            existing_type=sa.Integer(),
            comment="Diastolic blood pressure (mmHg)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hr",
            existing_type=sa.Integer(),
            comment="Heart rate (beats/minute)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, nausea/vomiting (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10, orientation/clouding of sensorium (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, tremor (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, paroxysmal sweats (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, anxiety (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, agitation (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, tactile disturbances (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, auditory disturbances (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, visual disturbances (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, headache/fullness in head (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rr",
            existing_type=sa.Integer(),
            comment="Respiratory rate (breaths/minute)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sbp",
            existing_type=sa.Integer(),
            comment="Systolic blood pressure (mmHg)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "t",
            existing_type=sa.Float(),
            comment="Temperature (degrees C)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("contactlog", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment="Comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "end",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Date/time that contact ended",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "location",
            existing_type=sa.Text(),
            comment="Location",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other_liaison",
            existing_type=sa.Integer(),
            comment=(
                "Liaison with others (e.g. family) involved (0 no, 1 yes)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_contact",
            existing_type=sa.Integer(),
            comment="Patient contact involved (0 no, 1 yes)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "staff_liaison",
            existing_type=sa.Integer(),
            comment="Liaison with staff involved (0 no, 1 yes)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Date/time that contact started",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cope_brief", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by",
            existing_type=sa.Text(),
            comment="Name of person task completed by (if not by patient)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by_patient",
            existing_type=sa.Integer(),
            comment="Task completed by patient? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1, work/activities to take mind off (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10, getting help/advice from others (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11, alcohol/drugs to get through it (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12, trying to see it in a more positive light (0 not at all"
                " - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13, criticizing myself (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14, trying to come up with a strategy (0 not at all - 3 a"
                " lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15, getting comfort/understanding from someone (0 not at all"
                " - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16, giving up the attempt to cope (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17, looking for something good in what's happening (0 not at"
                " all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment="Q18, making jokes about it (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19, doing something to think about it less (0 not at all - 3"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2, concentrating efforts on doing something about it (0 not"
                " at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20, accepting reality of the fact it's happened (0 not at"
                " all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21, expressing negative feelings (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=(
                "Q22, seeking comfort in religion/spirituality (0 not at all -"
                " 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=(
                "Q23, trying to get help/advice from others about what to do"
                " (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment="Q24, learning to live with it (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=(
                "Q25, thinking hard about what steps to take (0 not at all - 3"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment="Q26, blaming myself (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment="Q27, praying/meditating (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=(
                "Q28, making fun of the situation (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, saying it's unreal (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4, alcohol/drugs to feel better (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5, emotional support from others (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6, given up trying to deal with it (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7, taking action to make situation better (0 not at all - 3"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8, refusing to believe it's happened (0 not at all - 3 a"
                " lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9, saying things to let unpleasant feelings escape (0 not at"
                " all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "relationship_to_patient",
            existing_type=sa.Integer(),
            comment=(
                "Relationship of responder to patient (0 other, 1 wife, 2"
                " husband, 3 daughter, 4 son, 5 sister, 6 brother, 7 mother, 8"
                " father, 9 friend)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "relationship_to_patient_other",
            existing_type=sa.Text(),
            comment="Relationship of responder to patient (if OTHER chosen)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("core10", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (tension/anxiety) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (unwanted images) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (support) (0 most or all of the time - 4 not at all)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (coping) (0 most or all of the time - 4 not at all)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (talking is too much) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5 (panic) (0 not at all - 4 most or all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (suicidality) (0 not at all - 4 most or all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (sleep problems) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (despair/hopelessness) (0 not at all - 4 most or all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9 (unhappy) (0 not at all - 4 most or all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cpft_lps_discharge", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "diagnosis_no_active_mental_health_problem",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequent_attender",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "leaflet_or_discharge_card_given",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_accommodation_placement",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_assessment_diagnostic",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_capacity",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_complex_case_conference",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_education_carers",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_education_patient",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_education_staff",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_medication",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s136",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s2",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s3",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s5_2",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_nursing_management",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_signposting_external_referral",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_specialling_behavioural_disturbance",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_supportive_carers",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_supportive_patient",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_supportive_staff",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_therapy_cat",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_therapy_cbt",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_therapy_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_treatment_adherence",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_wanted_copy_of_letter",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_anxiety",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_behavioural_disturbance",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_capacity",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_cognitive_problem",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_delirium",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_discharge_placement",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_eating_disorder",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_elevated_mood",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_low_mood",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_motivation_adherence",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_post_transplant",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_pre_transplant",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_psychosis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_safeguarding",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_self_harm_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_self_harm_overdose",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_somatoform_mus",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_substance_alcohol",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_substance_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_suicidal_ideas",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("cpft_lps_referral", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_confusion",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_falls",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_infection",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_overdose",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_poor_adherence",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_self_harm_not_overdose",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_trauma",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "interpreter_required",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_aware_of_referral",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "sensory_impairment",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cpft_lps_resetresponseclock", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("dad", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "continence_exec_toilet",
            existing_type=sa.Integer(),
            comment="continence_exec_toilet (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "continence_init_toilet",
            existing_type=sa.Integer(),
            comment="continence_init_toilet (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_exec_dress",
            existing_type=sa.Integer(),
            comment="dressing_exec_dress (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_exec_undress",
            existing_type=sa.Integer(),
            comment="dressing_exec_undress (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_init_dress",
            existing_type=sa.Integer(),
            comment="dressing_init_dress (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_plan_clothing",
            existing_type=sa.Integer(),
            comment="dressing_plan_clothing (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_plan_order",
            existing_type=sa.Integer(),
            comment="dressing_plan_order (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eating_exec_eat",
            existing_type=sa.Integer(),
            comment="eating_exec_eat (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eating_init_eat",
            existing_type=sa.Integer(),
            comment="eating_init_eat (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eating_plan_utensils",
            existing_type=sa.Integer(),
            comment="eating_plan_utensils (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_exec_handle_money",
            existing_type=sa.Integer(),
            comment=(
                "finance_exec_handle_money (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_init_interest",
            existing_type=sa.Integer(),
            comment="finance_init_interest (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_plan_organise_correspondence",
            existing_type=sa.Integer(),
            comment=(
                "finance_plan_organise_correspondence (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_plan_pay_bills",
            existing_type=sa.Integer(),
            comment="finance_plan_pay_bills (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_exec_hair",
            existing_type=sa.Integer(),
            comment="hygiene_exec_hair (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_exec_teeth",
            existing_type=sa.Integer(),
            comment="hygiene_exec_teeth (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_exec_wash",
            existing_type=sa.Integer(),
            comment="hygiene_exec_wash (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_init_hair",
            existing_type=sa.Integer(),
            comment="hygiene_init_hair (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_init_teeth",
            existing_type=sa.Integer(),
            comment="hygiene_init_teeth (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_init_wash",
            existing_type=sa.Integer(),
            comment="hygiene_init_wash (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_plan_wash",
            existing_type=sa.Integer(),
            comment="hygiene_plan_wash (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "leisure_exec_complete_chores",
            existing_type=sa.Integer(),
            comment=(
                "leisure_exec_complete_chores (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_exec_safe_at_home",
            existing_type=sa.Integer(),
            comment=(
                "leisure_exec_safe_at_home (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_init_interest_chores",
            existing_type=sa.Integer(),
            comment=(
                "leisure_init_interest_chores (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_init_interest_leisure",
            existing_type=sa.Integer(),
            comment=(
                "leisure_init_interest_leisure (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_plan_chores",
            existing_type=sa.Integer(),
            comment="leisure_plan_chores (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mealprep_exec_meal",
            existing_type=sa.Integer(),
            comment="mealprep_exec_meal (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mealprep_init_meal",
            existing_type=sa.Integer(),
            comment="mealprep_init_meal (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mealprep_plan_meal",
            existing_type=sa.Integer(),
            comment="mealprep_plan_meal (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "medications_exec_take_medications",
            existing_type=sa.Integer(),
            comment=(
                "medications_exec_take_medications (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "medications_init_medication",
            existing_type=sa.Integer(),
            comment=(
                "medications_init_medication (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_exec_mode_transportation",
            existing_type=sa.Integer(),
            comment=(
                "outing_exec_mode_transportation (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_exec_reach_destination",
            existing_type=sa.Integer(),
            comment=(
                "outing_exec_reach_destination (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_exec_return_with_shopping",
            existing_type=sa.Integer(),
            comment=(
                "outing_exec_return_with_shopping (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_init_outing",
            existing_type=sa.Integer(),
            comment="outing_init_outing (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_plan_outing",
            existing_type=sa.Integer(),
            comment="outing_plan_outing (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "telephone_exec_conversation",
            existing_type=sa.Integer(),
            comment=(
                "telephone_exec_conversation (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "telephone_exec_message",
            existing_type=sa.Integer(),
            comment="telephone_exec_message (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "telephone_init_phone",
            existing_type=sa.Integer(),
            comment="telephone_init_phone (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "telephone_plan_dial",
            existing_type=sa.Integer(),
            comment="telephone_plan_dial (1 yes, 0 no, -99 not applicable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("dast", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=(
                'Q1. non-medical drug use (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=(
                'Q10. spouse/parents complain (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment=(
                'Q11. friends/relative know/suspect (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment=(
                'Q12. caused problems with spouse (+) ("+" = Y scores 1, "-" ='
                " N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment=(
                'Q13. family sought help (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment=(
                'Q14. lost friends (+) ("+" = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment=(
                'Q15. neglected family/missed work (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.String(length=1),
            comment=(
                'Q16. trouble at work (+) ("+" = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.String(length=1),
            comment='Q17. lost job (+) ("+" = Y scores 1, "-" = N scores 1)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.String(length=1),
            comment=(
                'Q18. fights under influence (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.String(length=1),
            comment=(
                'Q19. arrested for unusual behaviour under influence (+) ("+"'
                ' = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=(
                'Q2. abused prescription drugs (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.String(length=1),
            comment=(
                'Q20. arrested for driving under influence (+) ("+" = Y scores'
                ' 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.String(length=1),
            comment=(
                'Q21. illegal activities to obtain (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.String(length=1),
            comment=(
                'Q22. arrested for possession (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.String(length=1),
            comment=(
                'Q23. withdrawal symptoms (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.String(length=1),
            comment=(
                'Q24. medical problems (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.String(length=1),
            comment=(
                'Q25. sought help (+) ("+" = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.String(length=1),
            comment=(
                'Q26. hospital for medical problems (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.String(length=1),
            comment=(
                'Q27. drug treatment program (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.String(length=1),
            comment=(
                'Q28. outpatient treatment for drug abuse (+) ("+" = Y scores'
                ' 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=(
                'Q3. abused >1 drug at a time (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=(
                'Q4. get through week without drugs (-) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment=(
                'Q5. stop when want to (-) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=(
                'Q6. abuse drugs continuously (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment=(
                'Q7. try to limit to certain situations (-) ("+" = Y scores 1,'
                ' "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment=(
                'Q8. blackouts/flashbacks (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment=(
                'Q9. feel bad about drug abuse (-) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "deakin_1_healthreview", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergies", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "allergy_asthma",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergy_dander",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergy_dermatitis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergy_food", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "allergy_other", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "allergy_pollen_dust",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnicity",
            existing_type=sa.Integer(),
            comment="Ethnicity code, per GMC Patient Questionnaire (1-16)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnicity_other_details",
            existing_type=sa.Text(),
            comment="Ethnicity, other, details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnicity_text",
            existing_type=sa.Text(),
            comment="Ethnicity, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "family_history",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_arthritis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_bipolar",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_diabetes",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_graves",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_ms",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_psychosis_sz",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_sle",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "handedness",
            existing_type=sa.String(length=1),
            comment="Handedness (L, R)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "health_anything_else",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "immune_disorders",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_arthritis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_diabetes",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_graves",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_hiv", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "immunity_ms", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "immunity_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_sle", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "infection_chronic_gastroenteritis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_hepatitis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_respiratory",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_sexual",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_urinary",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_gastroenteritis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_hepatitis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_respiratory",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_sexual",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_urinary",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infections_chronic",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infections_last3months",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_claustrophobic",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_difficulty_lying_1_hour",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_metal_from_operations",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_nonremovable_metal",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_previous_brain_scan",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_tattoos_nicotine_patches",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_worked_with_metal",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other_relevant_things",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "recdrug_alcohol_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_alcohol_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_alcohol_unitsperweek",
            existing_type=sa.Integer(),
            comment="Alcohol: units per week",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_amphetamines_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_amphetamines_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_benzodiazepines_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_benzodiazepines_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cannabis_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cannabis_jointsperweek",
            existing_type=sa.Integer(),
            comment="Cannabis: joints per week",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cannabis_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cocaine_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cocaine_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_crack_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_crack_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_hallucinogens_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_hallucinogens_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_heroin_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_heroin_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_inhalants_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_inhalants_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_ketamine_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_ketamine_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_legalhighs_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_legalhighs_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_mdma_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_mdma_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_methadone_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_methadone_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_tobacco_cigsperweek",
            existing_type=sa.Integer(),
            comment="Tobacco: cigarettes per week",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_tobacco_frequency",
            existing_type=sa.Integer(),
            comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_tobacco_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recreational_drug_in_last_3_months",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vaccinations_last3months",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "willing_to_participate_in_further_studies",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )

    with op.batch_alter_table("demoquestionnaire", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("demqol", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1. cheerful (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10. lively (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11. irritable (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12. fed up (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13. couldn't do things (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14. worried: forget recent (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15. worried: forget people (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16. worried: forget day (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17. worried: muddled (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18. worried: difficulty making decisions (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19. worried: poor concentration (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2. worried/anxious (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20. worried: not enough company (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21. worried: get on with people close (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=(
                "Q22. worried: affection (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=(
                "Q23. worried: people not listening (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=(
                "Q24. worried: making self understood (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=(
                "Q25. worried: getting help (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=(
                "Q26. worried: toilet (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=(
                "Q27. worried: feel in self (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=(
                "Q28. worried: health overall (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=(
                "Q29. Overall quality of life (1 very good - 4 poor; -99 no"
                " response)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3. enjoying life (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4. frustrated (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5. confident (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6. full of energy (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7. sad (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8. lonely (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9. distressed (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("demqolproxy", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1. cheerful (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10. fed up (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11. things to look forward to (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12. worried: memory in general (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13. worried: forget distant (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14. worried: forget recent (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15. worried: forget people (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16. worried: forget place (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17. worried: forget day (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18. worried: muddled (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19. worried: difficulty making decisions (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2. worried/anxious (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20. worried: making self understood (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21. worried: keeping clean (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=(
                "Q22. worried: keeping self looking nice (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=(
                "Q23. worried: shopping (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=(
                "Q24. worried: using money to pay (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=(
                "Q25. worried: looking after finances (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=(
                "Q26. worried: taking longer (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=(
                "Q27. worried: getting in touch with people (1 a lot - 4 not"
                " at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=(
                "Q28. worried: not enough company (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=(
                "Q29. worried: not being able to help others (1 a lot - 4 not"
                " at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3. frustrated (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment=(
                "Q30. worried: not playing a useful part (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q31",
            existing_type=sa.Integer(),
            comment=(
                "Q31. worried: physical health (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q32",
            existing_type=sa.Integer(),
            comment=(
                "Q32. Overall quality of life (1 very good - 4 poor; -99 no"
                " response)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4. full of energy (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5. sad (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6. content (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7. distressed (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8. lively (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9. irritable (1 a lot - 4 not at all; -99 no response)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("diagnosis_icd10", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "relates_to_date",
            existing_type=sa.DATE(),
            comment="Date that diagnoses relate to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("diagnosis_icd10_item", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "code",
            existing_type=sa.String(length=7),
            comment="Diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment="Clinician's comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment="Description of the diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "diagnosis_icd10_id",
            existing_type=sa.Integer(),
            comment="FK to parent table",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "seqnum",
            existing_type=sa.Integer(),
            comment="Sequence number (consistently 1-based as of 2018-12-01)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("diagnosis_icd9cm", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "relates_to_date",
            existing_type=sa.DATE(),
            comment="Date that diagnoses relate to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "diagnosis_icd9cm_item", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "code",
            existing_type=sa.String(length=7),
            comment="Diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment="Clinician's comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment="Description of the diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "diagnosis_icd9cm_id",
            existing_type=sa.Integer(),
            comment="FK to parent table",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "seqnum",
            existing_type=sa.Integer(),
            comment="Sequence number (consistently 1-based as of 2018-12-01)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("distressthermometer", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress",
            existing_type=sa.Integer(),
            comment="Distress (0 none - 10 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other",
            existing_type=sa.Text(),
            comment="Other problems",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="1. child care (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="10. fears (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="11. nervousness (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="12. sadness (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="13. worry (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="14. loss of interest (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment="15. spiritual/religious (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="16. appearance (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="17. bathing/dressing (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment="18. breathing (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment="19. urination (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="2. housing (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment="20. constipation (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment="21. diarrhoea (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment="22. eating (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment="23. fatigue (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment="24. feeling swollen (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment="25. fevers (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment="26. getting around (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment="27. indigestion (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment="28. memory/concentration (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment="29. mouth sores (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="3. insurance/financial (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment="30. nausea (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q31",
            existing_type=sa.Integer(),
            comment="31. nose dry/congested (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q32",
            existing_type=sa.Integer(),
            comment="32. pain (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q33",
            existing_type=sa.Integer(),
            comment="33. sexual (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q34",
            existing_type=sa.Integer(),
            comment="34. skin dry/itchy (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q35",
            existing_type=sa.Integer(),
            comment="35. sleep (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q36",
            existing_type=sa.Integer(),
            comment="36. tingling in hands/feet (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="4. transportation (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="5. work/school (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="6. children (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="7. partner (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="8. close friend/relative (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="9. depression (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("epds", schema=None) as batch_op:
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("eq5d5l", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "health_vas",
            existing_type=sa.Integer(),
            comment=(
                "Visual analogue scale for overall health (0 worst - 100 best)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1 (mobility) (1 no problems - 5 unable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (self-care) (1 no problems - 5 unable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (usual activities) (1 no problems - 5 unable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4 (pain/discomfort) (1 none - 5 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5 (anxiety/depression) (1 not - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("factg", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q1",
            existing_type=sa.Integer(),
            comment=(
                "Emotional well-being Q1 (sad) (0 not at all, 1 a little bit,"
                " 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q2",
            existing_type=sa.Integer(),
            comment=(
                "Emotional well-being Q2 (satisfied with coping re illness) (0"
                " not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q3",
            existing_type=sa.Integer(),
            comment=(
                "Emotional well-being Q3 (losing hope in fight against"
                " illness) (0 not at all, 1 a little bit, 2 somewhat, 3 quite"
                " a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q4",
            existing_type=sa.Integer(),
            comment=(
                "Emotional well-being Q4 (nervousworried about dying) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q5",
            existing_type=sa.Integer(),
            comment=(
                "Emotional well-being Q5 (worried condition will worsen) (0"
                " not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q6",
            existing_type=sa.Integer(),
            comment=(
                "Emotional well-being Q6 () (0 not at all, 1 a little bit, 2"
                " somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q1",
            existing_type=sa.Integer(),
            comment=(
                "Functional well-being Q1 (able to work) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q2",
            existing_type=sa.Integer(),
            comment=(
                "Functional well-being Q2 (work fulfilling) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q3",
            existing_type=sa.Integer(),
            comment=(
                "Functional well-being Q3 (able to enjoy life) (0 not at all,"
                " 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q4",
            existing_type=sa.Integer(),
            comment=(
                "Functional well-being Q4 (accepted illness) (0 not at all, 1"
                " a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q5",
            existing_type=sa.Integer(),
            comment=(
                "Functional well-being Q5 (sleeping well) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q6",
            existing_type=sa.Integer(),
            comment=(
                "Functional well-being Q6 (enjoying usual fun things) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q7",
            existing_type=sa.Integer(),
            comment=(
                "Functional well-being Q7 (content with quality of life) (0"
                " not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "ignore_s_q7", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "p_q1",
            existing_type=sa.Integer(),
            comment=(
                "Physical well-being Q1 (lack of energy) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q2",
            existing_type=sa.Integer(),
            comment=(
                "Physical well-being Q2 (nausea) (0 not at all, 1 a little"
                " bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q3",
            existing_type=sa.Integer(),
            comment=(
                "Physical well-being Q3 (trouble meeting family needs) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q4",
            existing_type=sa.Integer(),
            comment=(
                "Physical well-being Q4 (pain) (0 not at all, 1 a little bit,"
                " 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q5",
            existing_type=sa.Integer(),
            comment=(
                "Physical well-being Q5 (treatment side effects) (0 not at"
                " all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q6",
            existing_type=sa.Integer(),
            comment=(
                "Physical well-being Q6 (feel ill) (0 not at all, 1 a little"
                " bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q7",
            existing_type=sa.Integer(),
            comment=(
                "Physical well-being Q7 (bedbound) (0 not at all, 1 a little"
                " bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "s_q1",
            existing_type=sa.Integer(),
            comment=(
                "Social well-being Q1 (close to friends) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q2",
            existing_type=sa.Integer(),
            comment=(
                "Social well-being Q2 (emotional support from family) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q3",
            existing_type=sa.Integer(),
            comment=(
                "Social well-being Q3 (support from friends) (0 not at all, 1"
                " a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q4",
            existing_type=sa.Integer(),
            comment=(
                "Social well-being Q4 (family accepted illness) (0 not at all,"
                " 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q5",
            existing_type=sa.Integer(),
            comment=(
                "Social well-being Q5 (good family comms re illness) (0 not at"
                " all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q6",
            existing_type=sa.Integer(),
            comment=(
                "Social well-being Q6 (feel close to partner/main supporter)"
                " (0 not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q7",
            existing_type=sa.Integer(),
            comment=(
                "Social well-being Q7 (satisfied with sex life) (0 not at all,"
                " 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("fast", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1. M>8, F>6 drinks (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2. unable to remember (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3. failed to do what was expected (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4. others concerned (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("fft", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment=(
                "Likelihood of recommendation to friends/family (1 extremely"
                " likely - 5 extremely unlikely, 6 don't know)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("frs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1, behaviour / lacks interest (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10, household / lacks interest/motivation (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11, household / difficulty completing chores (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12, household / telephoning (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13, finances / lacks interest (0 = never, 2 = always, 1 ="
                " sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14, finances / problems organizing finances (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15, finances / problems organizing correspondence (0 ="
                " never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16, finances / difficulty with cash (0 = never, 2 = always,"
                " 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17, medication / problems taking medication at correct time"
                " (0 = never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18, medication / problems taking medication as prescribed (0"
                " = never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19, mealprep / lacks interest/motivation (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2, behaviour / lacks affection (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20, mealprep / difficulty organizing meal prep (0 = never, 2"
                " = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21, mealprep / problems preparing meal on own (0 = never, 2"
                " = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=(
                "Q22, mealprep / lacks initiative to eat (0 = never, 2 ="
                " always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=(
                "Q23, mealprep / difficulty choosing utensils/seasoning (0 ="
                " never, 2 = always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=(
                "Q24, mealprep / problems eating (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=(
                "Q25, mealprep / wants to eat same foods repeatedly (0 ="
                " never, 2 = always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=(
                "Q26, mealprep / prefers sweet foods more (0 = never, 2 ="
                " always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=(
                "Q27, selfcare / problems choosing appropriate clothing (0 ="
                " never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=(
                "Q28, selfcare / incontinent (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=(
                "Q29, selfcare / cannot be left at home safely (0 = never, 2 ="
                " always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3, behaviour / uncooperative (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment="Q30, selfcare / bedbound (0 = never, 2 = always)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4, behaviour / confused/muddled in unusual surroundings (0 ="
                " never, 2 = always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5, behaviour / restless (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6, behaviour / impulsive (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7, behaviour / forgets day (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8, outings / transportation (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9, outings / shopping (0 = never, 2 = always, 1 = sometimes,"
                " -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("gad7", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1, nervous/anxious/on edge (0 not at all - 3 nearly every"
                " day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2, can't stop/control worrying (0 not at all - 3 nearly"
                " every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3, worrying too much about different things (0 not at all -"
                " 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, trouble relaxing (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, restless (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, irritable (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, afraid (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("gaf", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "score",
            existing_type=sa.Integer(),
            comment="GAF score (1-100 or 0 for insufficient information)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("gbogpc", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date",
            existing_type=sa.DATE(),
            comment="Session date",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_description",
            existing_type=sa.Text(),
            comment="Brief description of the goal",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_number",
            existing_type=sa.Integer(),
            comment="Goal number (1-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "progress",
            existing_type=sa.Integer(),
            comment="Progress towards goal (0 no progress - 10 reached fully)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "session",
            existing_type=sa.Integer(),
            comment="Session number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "whose_goal",
            existing_type=sa.Integer(),
            comment=(
                "Whose goal is this (1 = Patient/service user; 2 ="
                " Parent/carer; 3 = Practitioner/clinician; 4 = Other: )"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "whose_goal_other",
            existing_type=sa.Text(),
            comment="If 'whose goal' is 'other', who?",
            existing_nullable=True,
        )

    with op.batch_alter_table("gbogras", schema=None) as batch_op:
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rate_goal_1",
            existing_type=sa.Boolean(),
            existing_comment="Rate goal 1?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rate_goal_2",
            existing_type=sa.Boolean(),
            existing_comment="Rate goal 2?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rate_goal_3",
            existing_type=sa.Boolean(),
            existing_comment="Rate goal 3?",
            existing_nullable=True,
        )

    with op.batch_alter_table("gbogres", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by",
            existing_type=sa.Integer(),
            comment=(
                "Who completed the form (1 = Patient/service user; 2 ="
                " Parent/carer; 3 = Practitioner/clinician; 4 = Other: )"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by_other",
            existing_type=sa.Text(),
            comment="If completed by 'other', who?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date",
            existing_type=sa.DATE(),
            comment="Date of goal-setting",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_1_description",
            existing_type=sa.Text(),
            comment="Goal 1 description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_2_description",
            existing_type=sa.Text(),
            comment="Goal 2 description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_3_description",
            existing_type=sa.Text(),
            comment="Goal 3 description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other_goals",
            existing_type=sa.Text(),
            comment="Other/additional goal description(s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("gds15", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment="Q1, satisfied ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment="Q10, memory problems ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment="Q11, wonderful to be alive ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment="Q12, worthless ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment="Q13, full of energy ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment="Q14, hopeless ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment="Q15, others better off ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment="Q2, dropped activities ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment="Q3, life empty ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment="Q4, bored ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment="Q5, good spirits ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment="Q6, afraid ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment="Q7, happy ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment="Q8, helpless ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment="Q9, stay at home ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("gmcpq", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "doctor",
            existing_type=sa.Text(),
            comment="Doctor's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Filling in questionnaire for... (1 yourself, 2 child, 3"
                " spouse/partner, 4 other relative/friend)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment="Sex of rater (M, F)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Age (1 = under 15, 2 = 15-20, 3 = 21-40, 4 = 40-60, 5 = 60 or"
                " over"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Ethnicity (1 = White British, 2 = White Irish, 3 = White"
                " other, 4 = Mixed W/B Caribbean, 5 = Mixed W/B African, 6 ="
                " Mixed W/Asian, 7 = Mixed other, 8 = Asian/Asian British -"
                " Indian, 9 = A/AB - Pakistani, 10 = A/AB - Bangladeshi, 11 ="
                " A/AB - other, 12 = Black/Black British - Caribbean, 13 ="
                " B/BB - African, 14 = B/BB - other, 15 = Chinese, 16 = other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12_details",
            existing_type=sa.Text(),
            comment="Ethnic group, other, details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2a",
            existing_type=sa.Integer(),
            comment="Reason: advice? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2b",
            existing_type=sa.Integer(),
            comment="Reason: one-off problem? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2c",
            existing_type=sa.Integer(),
            comment="Reason: ongoing problem? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2d",
            existing_type=sa.Integer(),
            comment="Reason: routine check? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2e",
            existing_type=sa.Integer(),
            comment="Reason: treatment? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2f",
            existing_type=sa.Integer(),
            comment="Reason: other? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2f_details",
            existing_type=sa.Text(),
            comment="Reason, other, details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "How important to health/wellbeing was the reason (1 not very"
                " - 5 very)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4a",
            existing_type=sa.Integer(),
            comment=(
                "How good: being polite (1 poor - 5 very good, 0 does not"
                " apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4b",
            existing_type=sa.Integer(),
            comment=(
                "How good: making you feel at ease (1 poor - 5 very good, 0"
                " does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4c",
            existing_type=sa.Integer(),
            comment=(
                "How good: listening (1 poor - 5 very good, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4d",
            existing_type=sa.Integer(),
            comment=(
                "How good: assessing medical condition (1 poor - 5 very good,"
                " 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4e",
            existing_type=sa.Integer(),
            comment=(
                "How good: explaining (1 poor - 5 very good, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4f",
            existing_type=sa.Integer(),
            comment=(
                "How good: involving you in decisions (1 poor - 5 very good, 0"
                " does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4g",
            existing_type=sa.Integer(),
            comment=(
                "How good: providing/arranging treatment (1 poor - 5 very"
                " good, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5a",
            existing_type=sa.Integer(),
            comment=(
                "Agree/disagree: will keep info confidential (1 strongly"
                " disagree - 5 strongly agree, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5b",
            existing_type=sa.Integer(),
            comment=(
                "Agree/disagree: honest/trustworthy (1 strongly disagree - 5"
                " strongly agree, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Confident in doctor's ability to provide care (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Would be completely happy to see this doctor again (0 no, 1"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Was this visit with your usual doctor (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Text(),
            comment="Other comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("hads", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1: tense (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10: appearance (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11: restless (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12: anticipate (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13: panic (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14: book/TV/radio (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2: enjoy usual (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3: apprehensive (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4: laugh (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5: worry (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6: cheerful (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7: relaxed (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8: slow (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9: butterflies (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("hads_respondent", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1: tense (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10: appearance (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11: restless (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12: anticipate (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13: panic (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14: book/TV/radio (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2: enjoy usual (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3: apprehensive (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4: laugh (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5: worry (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6: cheerful (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7: relaxed (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8: slow (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9: butterflies (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("hama", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, anxious mood (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, respiratory (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, gastrointestinal (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, genitourinary (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13, other autonomic (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14, behaviour in interview (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, tension (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, fears (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, insomnia (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, concentration/memory (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, depressed mood (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, somatic, muscular (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, somatic, sensory (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, cardiovascular (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("hamd", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1, depressed mood (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10, anxiety, psychological (scored 0-4, except 0-2 for"
                " Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11, anxiety, somatic (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12, somatic symptoms, gastointestinal (scored 0-4, except"
                " 0-2 for Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13, somatic symptoms, general (scored 0-4, except 0-2 for"
                " Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14, genital symptoms (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15, hypochondriasis (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16a",
            existing_type=sa.Integer(),
            comment=(
                "Q16A, weight loss, by history (0 none - 2 definite, or 3 not"
                " assessed [not scored])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16b",
            existing_type=sa.Integer(),
            comment=(
                "Q16B, weight loss, by measurement (0 none - 2 more than 2lb,"
                " or 3 not assessed [not scored])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17, lack of insight (0-2, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18a",
            existing_type=sa.Integer(),
            comment=(
                "Q18A (not scored), diurnal variation, presence (0 none, 1"
                " worse AM, 2 worse PM)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18b",
            existing_type=sa.Integer(),
            comment=(
                "Q18B (not scored), diurnal variation, severity (0-2, higher"
                " more severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (not scored), depersonalization/derealization (0-4 for"
                " Q19, 0-3 for Q20, 0-2 for Q21, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2, guilt (scored 0-4, except 0-2 for Q4-6/12-14, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (not scored), paranoid symptoms (0-4 for Q19, 0-3 for"
                " Q20, 0-2 for Q21, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (not scored), obsessional/compulsive symptoms (0-4 for"
                " Q19, 0-3 for Q20, 0-2 for Q21, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3, suicide (scored 0-4, except 0-2 for Q4-6/12-14, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4, early insomnia (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5, middle insomnia (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6, late insomnia (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7, work/activities (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8, psychomotor retardation (scored 0-4, except 0-2 for"
                " Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9, agitation (scored 0-4, except 0-2 for Q4-6/12-14, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "whichq16",
            existing_type=sa.Integer(),
            comment=(
                "Method of assessing weight loss (0 = A, by history; 1 = B, by"
                " measured change)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("hamd7", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, depressed mood (0-4, except Q6 0-2; higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, guilt (0-4, except Q6 0-2; higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3, interest/pleasure/level of activities (0-4, except Q6"
                " 0-2; higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4, psychological anxiety (0-4, except Q6 0-2; higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, somatic anxiety (0-4, except Q6 0-2; higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6, energy/somatic symptoms (0-4, except Q6 0-2; higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, suicide (0-4, except Q6 0-2; higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("honos", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "period_rated",
            existing_type=sa.Text(),
            comment="Period being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1, overactive/aggressive/disruptive/agitated (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, activities of daily living (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, problems with living conditions (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, occupation/activities (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, deliberate self-harm (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, problem-drinking/drug-taking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, cognitive problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, physical illness/disability (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, hallucinations/delusions (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, depressed mood (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, other mental/behavioural problem (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8otherproblem",
            existing_type=sa.Text(),
            comment="Q8: other problem: specify",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8problemtype",
            existing_type=sa.String(length=1),
            comment=(
                "Q8: type of problem (A phobic; B anxiety; C"
                " obsessive-compulsive; D mental strain/tension; E"
                " dissociative; F somatoform; G eating; H sleep; I sexual; J"
                " other, specify)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, relationship problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("honos65", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "period_rated",
            existing_type=sa.Text(),
            comment="Period being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, behavioural disturbance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, activities of daily living (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, living conditions (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, occupation/activities (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, deliberate self-harm (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, problem drinking/drug-taking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, cognitive problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, physical illness/disability (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, hallucinations/delusions (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, depressive symptoms (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, other mental/behavioural problem (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8otherproblem",
            existing_type=sa.Text(),
            comment="Q8: other problem: specify",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8problemtype",
            existing_type=sa.String(length=1),
            comment=(
                "Q8: type of problem (A phobic; B anxiety; C"
                " obsessive-compulsive; D stress; E dissociative; F"
                " somatoform; G eating; H sleep; I sexual; J other, specify)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, relationship problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("honosca", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "period_rated",
            existing_type=sa.Text(),
            comment="Period being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, disruptive/antisocial/aggressive (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, peer relationships (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, self-care and independence (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, family life/relationships (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13, school attendance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14, problems with knowledge/understanding of child's"
                " problems (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15, lack of information about services (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, overactive/inattentive (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, self-harm (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, alcohol/drug misuse (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, scholastic/language problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, physical illness/disability (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, delusions/hallucinations (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, non-organic somatic symptoms (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, emotional symptoms (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10depressive", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "activity",
            existing_type=sa.Boolean(),
            comment=(
                "Change in psychomotor activity, with agitation or retardation"
                " (either subjective or objective)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anhedonia",
            existing_type=sa.Boolean(),
            comment=(
                "Loss of interest or pleasure in activities  that are normally"
                " pleasurable."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "appetite",
            existing_type=sa.Boolean(),
            comment=(
                "Change in appetite (decrease or increase) with corresponding"
                " weight change."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "concentration",
            existing_type=sa.Boolean(),
            comment=(
                "Complaints or evidence of diminished ability to think or"
                " concentrate, such as indecisiveness or vacillation."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "death",
            existing_type=sa.Boolean(),
            comment=(
                "Recurrent thoughts of death or suicide, or any suicidal"
                " behaviour."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_other",
            existing_type=sa.Boolean(),
            comment="Delusions (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_schizophrenic",
            existing_type=sa.Boolean(),
            comment=(
                "Delusions that are 'typically schizophrenic' (delusions of"
                " control, influence or passivity, clearly referred to body or"
                " limb movements or specific thoughts, actions, or sensations;"
                " delusional perception; persistent delusions of other kinds"
                " that are culturally inappropriate and completely"
                " impossible)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "duration_at_least_2_weeks",
            existing_type=sa.Boolean(),
            comment="Depressive episode lasts at least 2 weeks?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "energy",
            existing_type=sa.Boolean(),
            comment="Decreased energy or increased fatiguability.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "guilt",
            existing_type=sa.Boolean(),
            comment=(
                "Unreasonable feelings of self-reproach or excessive and"
                " inappropriate guilt."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_other",
            existing_type=sa.Boolean(),
            comment="Hallucinations (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_schizophrenic",
            existing_type=sa.Boolean(),
            comment=(
                "Hallucinations that are 'typically schizophrenic'"
                " (hallucinatory voices giving a running commentary on the"
                " patient's behaviour, or discussing him between themselves,"
                " or other types of hallucinatory voices coming from some part"
                " of the body)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mood",
            existing_type=sa.Boolean(),
            comment=(
                "Depressed mood to a degree that is definitely abnormal for"
                " the individual, present for most of the day and  almost"
                " every day, largely uninfluenced by circumstances, and"
                " sustained for at least 2 weeks."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "severe_clinically",
            existing_type=sa.Boolean(),
            comment=(
                "Clinical impression of severe depression, in a patient"
                " unwilling or unable to describe many symptoms in detail"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep",
            existing_type=sa.Boolean(),
            comment="Sleep disturbance of any type.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_anhedonia",
            existing_type=sa.Boolean(),
            comment=(
                "Marked loss of interest or pleasure in activities that are"
                " normally pleasurable"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_appetite",
            existing_type=sa.Boolean(),
            comment="Marked loss of appetite",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_early_morning_waking",
            existing_type=sa.Boolean(),
            comment=(
                "Waking in the morning 2 hours or more before the usual time"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_emotional_unreactivity",
            existing_type=sa.Boolean(),
            comment=(
                "Lack of emotional reactions to events or activities that"
                " normally produce an emotional response"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_libido",
            existing_type=sa.Boolean(),
            comment="Marked loss of libido",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_mood_worse_morning",
            existing_type=sa.Boolean(),
            comment="Depression worse in the morning",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_psychomotor",
            existing_type=sa.Boolean(),
            comment=(
                "Objective evidence of marked psychomotor retardation or"
                " agitation (remarked on or reported by other people)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_weight",
            existing_type=sa.Boolean(),
            comment=(
                "Weight loss (5 percent or more of body weight in the past"
                " month)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stupor",
            existing_type=sa.Boolean(),
            comment="Depressive stupor.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worth",
            existing_type=sa.Boolean(),
            comment="Loss of confidence and self-esteem.",
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10manic", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "activity",
            existing_type=sa.Boolean(),
            comment="Increased activity or physical restlessness.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_required",
            existing_type=sa.Boolean(),
            comment=(
                "Elevated/irritable mood severe enough to require hospital"
                " admission."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_other",
            existing_type=sa.Boolean(),
            comment="Delusions (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_schizophrenic",
            existing_type=sa.Boolean(),
            comment=(
                "Delusions that are 'typically schizophrenic' (delusions of"
                " control, influence or passivity, clearly referred to body or"
                " limb movements or specific thoughts, actions, or sensations;"
                " delusional perception; persistent delusions of other kinds"
                " that are culturally inappropriate and completely"
                " impossible)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distractible",
            existing_type=sa.Boolean(),
            comment=(
                "Difficulty in concentration or distractibility [from the"
                " criteria for hypomania]; distractibility or constant changes"
                " in activity or plans [from the criteria for mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "flight_of_ideas",
            existing_type=sa.Boolean(),
            comment=(
                "Flight of ideas or the subjective experience of thoughts"
                " racing."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "grandiosity",
            existing_type=sa.Boolean(),
            comment="Inflated self-esteem or grandiosity.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_other",
            existing_type=sa.Boolean(),
            comment="Hallucinations (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_schizophrenic",
            existing_type=sa.Boolean(),
            comment=(
                "Hallucinations that are 'typically schizophrenic'"
                " (hallucinatory voices giving a running commentary on the"
                " patient's behaviour, or discussing him between themselves,"
                " or other types of hallucinatory voices coming from some part"
                " of the body)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mood_elevated",
            existing_type=sa.Boolean(),
            comment=(
                "The mood is 'elevated' [hypomania] or 'predominantly elevated"
                " [or] expansive' [mania] to a degree that is definitely"
                " abnormal for the individual concerned."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mood_irritable",
            existing_type=sa.Boolean(),
            comment=(
                "The mood is 'irritable' [hypomania] or 'predominantly"
                " irritable' [mania] to a degree that is definitely abnormal"
                " for the individual concerned."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "perceptual_alterations",
            existing_type=sa.Boolean(),
            comment=(
                "Perceptual alterations (e.g. subjective hyperacusis,"
                " appreciation of colours as specially vivid, etc.)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recklessness",
            existing_type=sa.Boolean(),
            comment=(
                "Mild spending sprees, or other types of reckless or"
                " irresponsible behaviour [hypomania]; behaviour which is"
                " foolhardy or reckless and whose risks the subject does not"
                " recognize e.g. spending sprees, foolish enterprises,"
                " reckless driving [mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severe_interference_functioning",
            existing_type=sa.Boolean(),
            comment=(
                "Severe interference with personal functioning in daily"
                " living."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sexual",
            existing_type=sa.Boolean(),
            comment=(
                "Increased sexual energy [hypomania]; marked sexual energy or"
                " sexual indiscretions [mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep",
            existing_type=sa.Boolean(),
            comment="Decreased need for sleep.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "social_disinhibition",
            existing_type=sa.Boolean(),
            comment=(
                "Increased sociability or over-familiarity [hypomania]; loss"
                " of normal social inhibitions resulting in behaviour which is"
                " inappropriate to the circumstances [mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "some_interference_functioning",
            existing_type=sa.Boolean(),
            comment=(
                "Some interference with personal functioning in daily living."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sustained4days",
            existing_type=sa.Boolean(),
            comment="Elevated/irritable mood sustained for at least 4 days.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sustained7days",
            existing_type=sa.Boolean(),
            comment="Elevated/irritable mood sustained for at least 7 days.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "talkativeness",
            existing_type=sa.Boolean(),
            comment="Increased talkativeness (pressure of speech).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10mixed", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "duration_at_least_2_weeks",
            existing_type=sa.Boolean(),
            comment=(
                "Both manic and depressive symptoms must be prominent most of"
                " the time during a period of at least two weeks."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mixture_or_rapid_alternation",
            existing_type=sa.Boolean(),
            comment=(
                "The episode is characterized by either a mixture or a rapid"
                " alternation (i.e. within a few hours) of hypomanic, manic"
                " and depressive symptoms."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10schizophrenia", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "also_depressive",
            existing_type=sa.Boolean(),
            comment="Also meets criteria for depressive episode (F32)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "also_manic",
            existing_type=sa.Boolean(),
            comment="Also meets criteria for manic episode (F30)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "behaviour_change",
            existing_type=sa.Boolean(),
            comment=(
                "A significant and consistent change in the overall quality of"
                " some aspects of personal behaviour, manifest as loss of"
                " interest, aimlessness, idleness, a self-absorbed attitude,"
                " and social withdrawal."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "catatonia",
            existing_type=sa.Boolean(),
            comment=(
                "Catatonia: catatonic behaviour, such as excitement,"
                " posturing, or waxy flexibility, negativism, mutism, and"
                " stupor."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusional_perception",
            existing_type=sa.Boolean(),
            comment=(
                "Delusional perception [a normal perception, delusionally"
                " interpreted]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions",
            existing_type=sa.Boolean(),
            comment=(
                "Delusions: persistent delusions of other kinds that are"
                " culturally inappropriate and completely impossible, such as"
                " religious or political identity, or superhuman powers and"
                " abilities (e.g. being able to control the weather, or being"
                " in communication with aliens from another world)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_other",
            existing_type=sa.Boolean(),
            comment=(
                "Hallucinations: persistent hallucinations in any modality,"
                " when accompanied either by fleeting or half-formed delusions"
                " without clear affective content, or by persistent"
                " over-valued ideas, or when occurring every day for weeks or"
                " months on end."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hv_commentary",
            existing_type=sa.Boolean(),
            comment=(
                "Hallucinatory voices giving a running commentary on the"
                " patient's behaviour"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hv_discussing",
            existing_type=sa.Boolean(),
            comment=(
                "Hallucinatory voices discussing the patient among themselves"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hv_from_body",
            existing_type=sa.Boolean(),
            comment=(
                "Other types of hallucinatory voices coming from some part of"
                " the body"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "if_mood_psychosis_first",
            existing_type=sa.Boolean(),
            comment=(
                "If the patient also meets criteria for manic episode (F30) or"
                " depressive episode (F32), the criteria listed above must"
                " have been met before the disturbance of mood developed."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "negative",
            existing_type=sa.Boolean(),
            comment=(
                "Negative symptoms: 'negative' symptoms such as marked apathy,"
                " paucity of speech, and blunting or incongruity of emotional"
                " responses, usually resulting in social withdrawal and"
                " lowering of social performance; it must be clear that these"
                " are not due to depression or to neuroleptic medication."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "not_organic_or_substance",
            existing_type=sa.Boolean(),
            comment=(
                "The disorder is not attributable to organic brain disease (in"
                " the sense of F0), or to alcohol- or drug-related"
                " intoxication, dependence or withdrawal."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "passivity_bodily",
            existing_type=sa.Boolean(),
            comment=(
                "Passivity: delusions of control, influence, or passivity,"
                " clearly referred to body or limb movements..."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "passivity_mental",
            existing_type=sa.Boolean(),
            comment=(
                "(passivity) ... or to specific thoughts, actions, or"
                " sensations."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "performance_decline",
            existing_type=sa.Boolean(),
            comment=(
                "Marked decline in social, scholastic, or occupational"
                " performance."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "present_one_month",
            existing_type=sa.Boolean(),
            comment=(
                "Symptoms in groups A-C present for most of the time during an"
                " episode of psychotic illness lasting for at least one month"
                " (or at some time during most of the days)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_catatonic",
            existing_type=sa.Boolean(),
            comment=(
                "CATATONIC (F20.2): psychomotor disturbances dominate (such as"
                " stupor, mutism, excitement, posturing, negativism, rigidity,"
                " waxy flexibility, command automatisms, or verbal"
                " perseveration)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_cenesthopathic",
            existing_type=sa.Boolean(),
            comment=(
                "CENESTHOPATHIC (within OTHER F20.8): body image aberration"
                " (e.g. desomatization, loss of bodily boundaries, feelings of"
                " body size change) or abnormal bodily sensations (e.g."
                " numbness, stiffness, feeling strange, depersonalization, or"
                " sensations of pain, temperature, electricity, heaviness,"
                " lightness, or discomfort when touched) dominate."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_hebephrenic",
            existing_type=sa.Boolean(),
            comment=(
                "HEBEPHRENIC (F20.1): dominated by affective changes (shallow,"
                " flat, incongruous, or inappropriate affect) and either"
                " pronounced thought disorder or aimless, disjointed behaviour"
                " is present."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_paranoid",
            existing_type=sa.Boolean(),
            comment=(
                "PARANOID (F20.0): dominated by delusions or hallucinations."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_postschizophrenic_depression",
            existing_type=sa.Boolean(),
            comment=(
                "POST-SCHIZOPHRENIC DEPRESSION (F20.4): in which a depressive"
                " episode has developed for at least 2 weeks following a"
                " schizophrenic episode within the last 12 months and in which"
                " schizophrenic symptoms persist but are not as prominent as"
                " the depression."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_residual",
            existing_type=sa.Boolean(),
            comment=(
                "RESIDUAL (F20.5): in which previous psychotic episodes of"
                " schizophrenia have given way to a chronic condition with"
                " 'negative' symptoms of schizophrenia for at least 1 year."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_simple",
            existing_type=sa.Boolean(),
            comment=(
                "SIMPLE SCHIZOPHRENIA (F20.6), in which 'negative' symptoms"
                " (C) with a change in personal behaviour (D) develop for at"
                " least one year without any psychotic episodes (no symptoms"
                " from groups A or B or other hallucinations or well-formed"
                " delusions), and with a marked decline in social, scholastic,"
                " or occupational performance."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_undifferentiated",
            existing_type=sa.Boolean(),
            comment=(
                "UNDIFFERENTIATED (F20.3): schizophrenia with active psychosis"
                " fitting none or more than one of the above three types."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_broadcasting",
            existing_type=sa.Boolean(),
            comment=(
                "Thought broadcasting [the feeling that one's thoughts leave"
                " oneself and are diffused widely, or are audible to others,"
                " or that others think the same thoughts in unison]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_disorder",
            existing_type=sa.Boolean(),
            comment=(
                "Thought disorder: breaks or interpolations in the train of"
                " thought, resulting in incoherence or irrelevant speech, or"
                " neologisms."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_echo",
            existing_type=sa.Boolean(),
            comment=(
                "Thought echo [hearing one's own thoughts aloud, just before,"
                " just after, or simultaneously with the thought]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_insertion",
            existing_type=sa.Boolean(),
            comment=(
                "Thought insertion [the feeling that one's thoughts have been"
                " placed there from outside]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_withdrawal",
            existing_type=sa.Boolean(),
            comment=(
                "Thought withdrawal [the feeling that one's thoughts have been"
                " removed by an outside agency]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10schizotypal", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a1",
            existing_type=sa.Boolean(),
            comment="Criterion A(1), inappropriate/constricted affect",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a2",
            existing_type=sa.Boolean(),
            comment="Criterion A(2), odd/eccentric/peculiar",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a3",
            existing_type=sa.Boolean(),
            comment="Criterion A(3), poor rapport/social withdrawal",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a4",
            existing_type=sa.Boolean(),
            comment="Criterion A(4), odd beliefs/magical thinking",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a5",
            existing_type=sa.Boolean(),
            comment="Criterion A(5), suspiciousness/paranoid ideas",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a6",
            existing_type=sa.Boolean(),
            comment="Criterion A(6), ruminations without inner resistance",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a7",
            existing_type=sa.Boolean(),
            comment="Criterion A(7), unusual perceptual experiences",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a8",
            existing_type=sa.Boolean(),
            comment=(
                "Criterion A(8),"
                " vague/circumstantial/metaphorical/over-elaborate/stereotyped"
                " thinking"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a9",
            existing_type=sa.Boolean(),
            comment=(
                "Criterion A(9), occasional transient quasi-psychotic episodes"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "b",
            existing_type=sa.Boolean(),
            comment=(
                "Criterion (B). True if: the subject has never met the"
                " criteria for any disorder in F20 (Schizophrenia)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10specpd", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic1",
            existing_type=sa.Boolean(),
            comment="Anankastic (1): doubt/caution",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic2",
            existing_type=sa.Boolean(),
            comment="Anankastic (2): preoccupation with details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic3",
            existing_type=sa.Boolean(),
            comment="Anankastic (3): perfectionism",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic4",
            existing_type=sa.Boolean(),
            comment="Anankastic (4): excessively conscientious",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic5",
            existing_type=sa.Boolean(),
            comment="Anankastic (5): preoccupied with productivity",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic6",
            existing_type=sa.Boolean(),
            comment="Anankastic (6): excessive pedantry",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic7",
            existing_type=sa.Boolean(),
            comment="Anankastic (7): rigid/stubborn",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic8",
            existing_type=sa.Boolean(),
            comment="Anankastic (8): require others do things specific way",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious1",
            existing_type=sa.Boolean(),
            comment="Anxious (1), tension/apprehension",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious2",
            existing_type=sa.Boolean(),
            comment="Anxious (2), preoccupied with criticism/rejection",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious3",
            existing_type=sa.Boolean(),
            comment="Anxious (3), won't get involved unless certain liked",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious4",
            existing_type=sa.Boolean(),
            comment="Anxious (4), need for security restricts lifestyle",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious5",
            existing_type=sa.Boolean(),
            comment="Anxious (5), avoidance of interpersonal contact",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent1",
            existing_type=sa.Boolean(),
            comment="Dependent (1): others decide",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent2",
            existing_type=sa.Boolean(),
            comment="Dependent (2): subordinate needs to those of others",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent3",
            existing_type=sa.Boolean(),
            comment="Dependent (3): unwilling to make reasonable demands",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent4",
            existing_type=sa.Boolean(),
            comment="Dependent (4): uncomfortable/helpless when alone",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent5",
            existing_type=sa.Boolean(),
            comment="Dependent (5): fears of being left to oneself",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent6",
            existing_type=sa.Boolean(),
            comment=(
                "Dependent (6): everyday decisions require advice/reassurance"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial1",
            existing_type=sa.Boolean(),
            comment="Dissocial (1): unconcern",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial2",
            existing_type=sa.Boolean(),
            comment="Dissocial (2): irresponsibility",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial3",
            existing_type=sa.Boolean(),
            comment="Dissocial (3): incapacity to maintain relationships",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial4",
            existing_type=sa.Boolean(),
            comment="Dissocial (4): low tolerance to frustration",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial5",
            existing_type=sa.Boolean(),
            comment="Dissocial (5): incapacity for guilt",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial6",
            existing_type=sa.Boolean(),
            comment="Dissocial (6): prone to blame others",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu1",
            existing_type=sa.Boolean(),
            comment=(
                "Emotionally unstable (1): act without considering"
                " consequences"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu10",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (10): feelings of emptiness",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu2",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (2): quarrelsome",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu3",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (3): outbursts of anger",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu4",
            existing_type=sa.Boolean(),
            comment=(
                "Emotionally unstable (4): can't maintain actions with"
                " immediate reward"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu5",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (5): unstable/capricious mood",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu6",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (6): uncertain self-image",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu7",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (7): intense/unstable relationships",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu8",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (8): avoids abandonment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu9",
            existing_type=sa.Boolean(),
            comment="Emotionally unstable (9): threats/acts of self-harm",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1",
            existing_type=sa.Boolean(),
            comment="G1: pathological 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_1",
            existing_type=sa.Boolean(),
            comment="G11: cognition",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_2",
            existing_type=sa.Boolean(),
            comment="G12: affectivity",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_3",
            existing_type=sa.Boolean(),
            comment="G13: impulse control",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_4",
            existing_type=sa.Boolean(),
            comment="G14: interpersonal",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g2",
            existing_type=sa.Boolean(),
            comment="G2: pervasive",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g3",
            existing_type=sa.Boolean(),
            comment="G3: pathological 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g4",
            existing_type=sa.Boolean(),
            comment="G4: persistent",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g5",
            existing_type=sa.Boolean(),
            comment="G5: primary 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g6",
            existing_type=sa.Boolean(),
            comment="G6: primary 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic1",
            existing_type=sa.Boolean(),
            comment="Histrionic (1): theatricality",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic2",
            existing_type=sa.Boolean(),
            comment="Histrionic (2): suggestibility",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic3",
            existing_type=sa.Boolean(),
            comment="Histrionic (3): shallow/labile affect",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic4",
            existing_type=sa.Boolean(),
            comment="Histrionic (4): centre of attention",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic5",
            existing_type=sa.Boolean(),
            comment="Histrionic (5): inappropriately seductive",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic6",
            existing_type=sa.Boolean(),
            comment="Histrionic (6): concerned with attractiveness",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other_pd_present",
            existing_type=sa.Boolean(),
            comment="Is another personality disorder present?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid1",
            existing_type=sa.Boolean(),
            comment="Paranoid (1): sensitive",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid2",
            existing_type=sa.Boolean(),
            comment="Paranoid (2): grudges",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid3",
            existing_type=sa.Boolean(),
            comment="Paranoid (3): suspicious",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid4",
            existing_type=sa.Boolean(),
            comment="Paranoid (4): personal rights",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid5",
            existing_type=sa.Boolean(),
            comment="Paranoid (5): sexual jealousy",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid6",
            existing_type=sa.Boolean(),
            comment="Paranoid (6): self-referential",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid7",
            existing_type=sa.Boolean(),
            comment="Paranoid (7): conspiratorial",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "schizoid1",
            existing_type=sa.Boolean(),
            comment="Schizoid (1): little pleasure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid2",
            existing_type=sa.Boolean(),
            comment="Schizoid (2): cold/detached",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid3",
            existing_type=sa.Boolean(),
            comment="Schizoid (3): limited capacity for warmth",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid4",
            existing_type=sa.Boolean(),
            comment="Schizoid (4): indifferent to praise/criticism",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid5",
            existing_type=sa.Boolean(),
            comment="Schizoid (5): little interest in sex",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid6",
            existing_type=sa.Boolean(),
            comment="Schizoid (6): solitary",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid7",
            existing_type=sa.Boolean(),
            comment="Schizoid (7): fantasy/introspection",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid8",
            existing_type=sa.Boolean(),
            comment="Schizoid (8): 0/1 close friends/confidants",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid9",
            existing_type=sa.Boolean(),
            comment="Schizoid (9): insensitive to social norms",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_anankastic",
            existing_type=sa.Boolean(),
            comment="Skip questions for anankastic PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_anxious",
            existing_type=sa.Boolean(),
            comment="Skip questions for anxious PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_dependent",
            existing_type=sa.Boolean(),
            comment="Skip questions for dependent PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_dissocial",
            existing_type=sa.Boolean(),
            comment="Skip questions for dissocial PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_eu",
            existing_type=sa.Boolean(),
            comment="Skip questions for emotionally unstable PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_histrionic",
            existing_type=sa.Boolean(),
            comment="Skip questions for histrionic PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_paranoid",
            existing_type=sa.Boolean(),
            comment="Skip questions for paranoid PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_schizoid",
            existing_type=sa.Boolean(),
            comment="Skip questions for schizoid PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vignette",
            existing_type=sa.Text(),
            comment="Vignette",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ided3d", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aborted",
            existing_type=sa.Integer(),
            comment="Was the task aborted? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "colour_definitions_rgb",
            existing_type=sa.Text(),
            comment="JSON-encoded version of colour RGB definitions",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "counterbalance_dimensions",
            existing_type=sa.Integer(),
            comment="Dimensional counterbalancing condition (0-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "debug_display_stimuli_only",
            existing_type=sa.Boolean(),
            comment="DEBUG: show stimuli only, don't run task",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finished",
            existing_type=sa.Integer(),
            comment="Was the task finished? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "iti_ms",
            existing_type=sa.Integer(),
            comment="Intertrial interval (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_stage",
            existing_type=sa.Integer(),
            comment="Last stage to offer (1 [SD] - 8 [EDR])",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_trial_completed",
            existing_type=sa.Integer(),
            comment="Number of last trial completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "max_number",
            existing_type=sa.Integer(),
            comment="Maximum number of stimulus element to use",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "max_trials_per_stage",
            existing_type=sa.Integer(),
            comment=(
                "Maximum number of trials allowed per stage before the task"
                " aborts"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "min_number",
            existing_type=sa.Integer(),
            comment="Minimum number of stimulus element to use",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "offer_abort",
            existing_type=sa.Boolean(),
            comment="Offer an abort button?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "pause_after_beep_ms",
            existing_type=sa.Integer(),
            comment=(
                "Time to continue visual feedback after auditory feedback"
                " finished (ms)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "progress_criterion_x",
            existing_type=sa.Integer(),
            comment=(
                "Criterion to proceed to next stage: X correct out of the last"
                " Y trials, where this is X"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "progress_criterion_y",
            existing_type=sa.Integer(),
            comment=(
                "Criterion to proceed to next stage: X correct out of the last"
                " Y trials, where this is Y"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "shape_definitions_svg",
            existing_type=sa.Text(),
            comment=(
                "JSON-encoded version of shape definition array in SVG format"
                " (with arbitrary scale of -60 to +60 in both X and Y"
                " dimensions)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "volume",
            existing_type=sa.Float(),
            comment="Sound volume (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ided3d_stages", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_exemplar",
            existing_type=sa.Text(),
            comment="Correct exemplar (from relevant dimension)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_stimulus_colours",
            existing_type=sa.Text(),
            comment=(
                "Possible colours for correct stimulus (CSV list of HTML"
                " colours)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_stimulus_numbers",
            existing_type=sa.Text(),
            comment=(
                "Possible numbers for correct stimulus (CSV list of numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_stimulus_shapes",
            existing_type=sa.Text(),
            comment=(
                "Possible shapes for correct stimulus (CSV list of shape"
                " numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "first_trial_num",
            existing_type=sa.Integer(),
            comment="Number of the first trial of the stage (1-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "ided3d_id",
            existing_type=sa.Integer(),
            comment="FK to ided3d",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "incorrect_exemplar",
            existing_type=sa.Text(),
            comment="Incorrect exemplar (from relevant dimension)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_stimulus_colours",
            existing_type=sa.Text(),
            comment=(
                "Possible colours for incorrect stimulus (CSV list of HTML"
                " colours)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_stimulus_numbers",
            existing_type=sa.Text(),
            comment=(
                "Possible numbers for incorrect stimulus (CSV list of numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_stimulus_shapes",
            existing_type=sa.Text(),
            comment=(
                "Possible shapes for incorrect stimulus (CSV list of shape"
                " numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_completed_trials",
            existing_type=sa.Integer(),
            comment="Number of trials completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_correct",
            existing_type=sa.Integer(),
            comment="Number of trials performed correctly",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_incorrect",
            existing_type=sa.Integer(),
            comment="Number of trials performed incorrectly",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "relevant_dimension",
            existing_type=sa.Text(),
            comment="Relevant dimension (e.g. shape, colour, number)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage",
            existing_type=sa.Integer(),
            comment="Stage number (1-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "stage_failed",
            existing_type=sa.Boolean(),
            comment="Subject took too many trials and failed stage",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage_name",
            existing_type=sa.Text(),
            comment="Name of the stage (e.g. SD, EDr)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage_passed",
            existing_type=sa.Boolean(),
            comment="Subject met criterion and passed stage",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ided3d_trials", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct",
            existing_type=sa.Boolean(),
            comment="Response was correct",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_colour",
            existing_type=sa.Text(),
            comment="HTML colour of correct stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_location",
            existing_type=sa.Integer(),
            comment=(
                "Location of correct stimulus (0 top, 1 right, 2 bottom, 3"
                " left)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_number",
            existing_type=sa.Integer(),
            comment="Number of copies of correct stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_shape",
            existing_type=sa.Integer(),
            comment="Shape# of correct stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "ided3d_id",
            existing_type=sa.Integer(),
            comment="FK to ided3d",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "incorrect",
            existing_type=sa.Boolean(),
            comment="Response was incorrect",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_colour",
            existing_type=sa.Text(),
            comment="HTML colour of incorrect stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_location",
            existing_type=sa.Integer(),
            comment=(
                "Location of incorrect stimulus (0 top, 1 right, 2 bottom, 3"
                " left)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_number",
            existing_type=sa.Integer(),
            comment="Number of copies of incorrect stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_shape",
            existing_type=sa.Integer(),
            comment="Shape# of incorrect stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "responded",
            existing_type=sa.Boolean(),
            comment="Did the subject respond?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_latency_ms",
            existing_type=sa.Integer(),
            comment="Response latency (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Time of response (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage",
            existing_type=sa.Integer(),
            comment="Stage number (1-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial",
            existing_type=sa.Integer(),
            comment="Trial number (1-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "trial_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Trial start time / stimuli presented at (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("iesr", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "event",
            existing_type=sa.Text(),
            comment="Relevant event",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, reminder feelings (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, jumpy (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, avoided thinking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, feelings undealt (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13, numb (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14, as if then (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment="Q15, sleep initiation (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="Q16, waves of emotion (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17, tried forgetting (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment="Q18, concentration (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment="Q19, reminder physical (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, sleep maintenance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment="Q20, dreams (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment="Q21, vigilant (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment="Q22, avoided talking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, reminder thinking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, irritable (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, avoided getting upset (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, thought unwanted (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, unreal (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, avoided reminder (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, mental pictures (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ifs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1. Motor series (motor programming)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2. Conflicting instructions (interference sensitivity)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3. Go/no-go (inhibitory control)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len2_1",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 2, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len2_2",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 2, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len3_1",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 3, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len3_2",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 3, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len4_1",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 4, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len4_2",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 4, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len5_1",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 5, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len5_2",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 5, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len6_1",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 6, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len6_2",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 6, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len7_1",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 7, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len7_2",
            existing_type=sa.Boolean(),
            comment="Q4. Digits backward, length 7, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5. Verbal working memory",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq1",
            existing_type=sa.Integer(),
            comment="Q6. Spatial working memory, sequence 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq2",
            existing_type=sa.Integer(),
            comment="Q6. Spatial working memory, sequence 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq3",
            existing_type=sa.Integer(),
            comment="Q6. Spatial working memory, sequence 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq4",
            existing_type=sa.Integer(),
            comment="Q6. Spatial working memory, sequence 4",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7_proverb1",
            existing_type=sa.Float(),
            comment=(
                "Q7. Proverb 1 (1 = correct explanation, 0.5 = example, 0 ="
                " neither)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7_proverb2",
            existing_type=sa.Float(),
            comment=(
                "Q7. Proverb 2 (1 = correct explanation, 0.5 = example, 0 ="
                " neither)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7_proverb3",
            existing_type=sa.Float(),
            comment=(
                "Q7. Proverb 3 (1 = correct explanation, 0.5 = example, 0 ="
                " neither)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8_sentence1",
            existing_type=sa.Integer(),
            comment="Q8. Hayling, sentence 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8_sentence2",
            existing_type=sa.Integer(),
            comment="Q8. Hayling, sentence 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8_sentence3",
            existing_type=sa.Integer(),
            comment="Q8. Hayling, sentence 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("irac", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "achieved",
            existing_type=sa.Integer(),
            comment="Was the aim achieved? (0 not, 1 partially, 2 fully)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aim",
            existing_type=sa.Text(),
            comment="Main aim of the contact",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "khandaker_1_medicalhistory", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cancer_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "cerebralpalsy_otherbrain_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cva_headinjury_braintumour_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dermatological_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "diabetes_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "epilepsy_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gastrointestinal_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "haematological_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "heart_disorder_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "infections_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "ms_pd_dementia_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "musculoskeletal_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other_endocrinological_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other_inflammatory_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "renal_urinary_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respiratory_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_impairment_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("mast", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment="Q1: feel you are a normal drinker (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment="Q10: drinking caused problems with relatives (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment="Q11: family have sought help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment="Q12: lost friends (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment="Q13: trouble at work/school (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment="Q14: lost job (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment="Q15: neglected obligations for >=2 days (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.String(length=1),
            comment="Q16: drink before noon often (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.String(length=1),
            comment="Q17: liver trouble (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.String(length=1),
            comment="Q18: delirium tremens (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.String(length=1),
            comment="Q19: sought help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment="Q2: couldn't remember evening before (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.String(length=1),
            comment="Q20: hospitalized (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.String(length=1),
            comment="Q21: psychiatry admission (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.String(length=1),
            comment="Q22: clinic visit or professional help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.String(length=1),
            comment="Q23: arrested for drink-driving (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.String(length=1),
            comment="Q24: arrested for other drunk behaviour (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment="Q3: relative worries/complains (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment="Q4: stop drinking after 1-2 drinks (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment="Q5: feel guilty (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=(
                "Q6: friends/relatives think you are a normal drinker (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment="Q7: can stop drinking when you want (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment="Q8: attended Alcoholics Anonymous (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment="Q9: physical fights (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("mds_updrs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1_1",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_10",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.10  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_11",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.11  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_12",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.12  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_13",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.13  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_2",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_3",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.3  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_4",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.4  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_5",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.5  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_6",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.6  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_6a",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.6a: informant for Q1.7-1.13 (0 patient, 1"
                " caregiver, 2 both)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_7",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.7  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_8",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.8  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_9",
            existing_type=sa.Integer(),
            comment=(
                "Part I, Q1.9  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1a",
            existing_type=sa.Integer(),
            comment=(
                "Part I: informant for Q1.1-1.6 (0 patient, 1 caregiver, 2"
                " both)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_1",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_10",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.10  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_11",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.11  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_12",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.12  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_13",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.13  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_2",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_3",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.3  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_4",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.4  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_5",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.5  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_6",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.6  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_7",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.7  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_8",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.8  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_9",
            existing_type=sa.Integer(),
            comment=(
                "Part II, Q2.9  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_1",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_10",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.10  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_11",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.11  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_12",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.12  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_13",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.13  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_14",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.14  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_15a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.15a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_15b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.15b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_16a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.16a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_16b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.16b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.17a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.17b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17c",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.17c  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17d",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.17d  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17e",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.17e  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_18",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.18  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_2",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.3a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.3b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3c",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.3c  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3d",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.3d  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3e",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.3e  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_4a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.4a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_4b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.4b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_5a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.5a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_5b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.5b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_6a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.6a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_6b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.6b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_7a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.7a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_7b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.7b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_8a",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.8a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_8b",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.8b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_9",
            existing_type=sa.Integer(),
            comment=(
                "Part III, Q3.9  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_dyskinesia_interfered",
            existing_type=sa.Boolean(),
            comment="Part III, q3_dyskinesia_interfered  (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_dyskinesia_present",
            existing_type=sa.Boolean(),
            comment="Part III, q3_dyskinesia_present  (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_hy_stage",
            existing_type=sa.Integer(),
            comment="Part III, q3_hy_stage (0-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3a",
            existing_type=sa.Boolean(),
            comment="Part III, Q3a (medication)  (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3b",
            existing_type=sa.Boolean(),
            comment="Part III, Q3b (clinical state)  (0 off, 1 on)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3c",
            existing_type=sa.Boolean(),
            comment="Part III, Q3c (levodopa)  (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3c1",
            existing_type=sa.Float(),
            comment="Part III, Q3c.1 (minutes since last dose)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_1",
            existing_type=sa.Integer(),
            comment=(
                "Part IV, Q4.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_2",
            existing_type=sa.Integer(),
            comment=(
                "Part IV, Q4.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_3",
            existing_type=sa.Integer(),
            comment=(
                "Part IV, Q4.3  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_4",
            existing_type=sa.Integer(),
            comment=(
                "Part IV, Q4.4  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_5",
            existing_type=sa.Integer(),
            comment=(
                "Part IV, Q4.5  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_6",
            existing_type=sa.Integer(),
            comment=(
                "Part IV, Q4.6  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("moca", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clockpicture_blobid",
            existing_type=sa.Integer(),
            comment="BLOB ID of clock picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cubepicture_blobid",
            existing_type=sa.Integer(),
            comment="BLOB ID of cube picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "education12y_or_less",
            existing_type=sa.Integer(),
            comment="<=12 years of education (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1 (VSE/path) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10 (attention/3 digits) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11 (attention/tapping) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12 (attention/serial 7s) (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13 (language/sentence 1) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14 (language/sentence 2) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment="Q15 (language/fluency) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="Q16 (abstraction 1) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17 (abstraction 2) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment="Q18 (recall word/face) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment="Q19 (recall word/velvet) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (VSE/cube) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment="Q20 (recall word/church) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment="Q21 (recall word/daisy) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment="Q22 (recall word/red) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment="Q23 (orientation/date) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment="Q24 (orientation/month) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment="Q25 (orientation/year) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment="Q26 (orientation/day) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment="Q27 (orientation/place) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment="Q28 (orientation/city) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (VSE/clock/contour) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4 (VSE/clock/numbers) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5 (VSE/clock/hands) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6 (naming/lion) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7 (naming/rhino) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8 (naming/camel) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9 (attention/5 digits) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_1",
            existing_type=sa.Integer(),
            comment="Recall with category cue (not scored), 1: FACE (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_2",
            existing_type=sa.Integer(),
            comment=(
                "Recall with category cue (not scored), 2: VELVET (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_3",
            existing_type=sa.Integer(),
            comment=(
                "Recall with category cue (not scored), 3: CHURCH (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_4",
            existing_type=sa.Integer(),
            comment="Recall with category cue (not scored), 4: DAISY (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_5",
            existing_type=sa.Integer(),
            comment="Recall with category cue (not scored), 5: RED (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_1",
            existing_type=sa.Integer(),
            comment=(
                "Recall with multiple-choice cue (not scored), 1: FACE (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_2",
            existing_type=sa.Integer(),
            comment=(
                "Recall with multiple-choice cue (not scored), 2: VELVET (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_3",
            existing_type=sa.Integer(),
            comment=(
                "Recall with multiple-choice cue (not scored), 3: CHURCH (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_4",
            existing_type=sa.Integer(),
            comment=(
                "Recall with multiple-choice cue (not scored), 4: DAISY (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_5",
            existing_type=sa.Integer(),
            comment=(
                "Recall with multiple-choice cue (not scored), 5: RED (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_1",
            existing_type=sa.Integer(),
            comment="Registration, trial 1 (not scored), 1: FACE (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_2",
            existing_type=sa.Integer(),
            comment="Registration, trial 1 (not scored), 2: VELVET (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_3",
            existing_type=sa.Integer(),
            comment="Registration, trial 1 (not scored), 3: CHURCH (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_4",
            existing_type=sa.Integer(),
            comment="Registration, trial 1 (not scored), 4: DAISY (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_5",
            existing_type=sa.Integer(),
            comment="Registration, trial 1 (not scored), 5: RED (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_1",
            existing_type=sa.Integer(),
            comment="Registration, trial 2 (not scored), 1: FACE (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_2",
            existing_type=sa.Integer(),
            comment="Registration, trial 2 (not scored), 2: VELVET (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_3",
            existing_type=sa.Integer(),
            comment="Registration, trial 2 (not scored), 3: CHURCH (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_4",
            existing_type=sa.Integer(),
            comment="Registration, trial 2 (not scored), 4: DAISY (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_5",
            existing_type=sa.Integer(),
            comment="Registration, trial 2 (not scored), 5: RED (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trailpicture_blobid",
            existing_type=sa.Integer(),
            comment="BLOB ID of trail picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("nart", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "abstemious",
            existing_type=sa.Boolean(),
            comment="Pronounced abstemious correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ache",
            existing_type=sa.Boolean(),
            comment="Pronounced ache correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aeon",
            existing_type=sa.Boolean(),
            comment="Pronounced aeon correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aisle",
            existing_type=sa.Boolean(),
            comment="Pronounced aisle correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "assignate",
            existing_type=sa.Boolean(),
            comment="Pronounced assignate correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aver",
            existing_type=sa.Boolean(),
            comment="Pronounced aver correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "banal",
            existing_type=sa.Boolean(),
            comment="Pronounced banal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "beatify",
            existing_type=sa.Boolean(),
            comment="Pronounced beatify correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bouquet",
            existing_type=sa.Boolean(),
            comment="Pronounced bouquet correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "campanile",
            existing_type=sa.Boolean(),
            comment="Pronounced campanile correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "capon",
            existing_type=sa.Boolean(),
            comment="Pronounced capon correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "catacomb",
            existing_type=sa.Boolean(),
            comment="Pronounced catacomb correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cellist",
            existing_type=sa.Boolean(),
            comment="Pronounced cellist correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "chord",
            existing_type=sa.Boolean(),
            comment="Pronounced chord correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "courteous",
            existing_type=sa.Boolean(),
            comment="Pronounced courteous correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "debt",
            existing_type=sa.Boolean(),
            comment="Pronounced debt correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "demesne",
            existing_type=sa.Boolean(),
            comment="Pronounced demesne correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "deny",
            existing_type=sa.Boolean(),
            comment="Pronounced deny correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depot",
            existing_type=sa.Boolean(),
            comment="Pronounced depot correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "detente",
            existing_type=sa.Boolean(),
            comment="Pronounced detente correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "drachm",
            existing_type=sa.Boolean(),
            comment="Pronounced drachm correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "equivocal",
            existing_type=sa.Boolean(),
            comment="Pronounced equivocal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "facade",
            existing_type=sa.Boolean(),
            comment="Pronounced facade correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gaoled",
            existing_type=sa.Boolean(),
            comment="Pronounced gaoled correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gauche",
            existing_type=sa.Boolean(),
            comment="Pronounced gauche correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gist",
            existing_type=sa.Boolean(),
            comment="Pronounced gist correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gouge",
            existing_type=sa.Boolean(),
            comment="Pronounced gouge correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "heir",
            existing_type=sa.Boolean(),
            comment="Pronounced heir correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hiatus",
            existing_type=sa.Boolean(),
            comment="Pronounced hiatus correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "idyll",
            existing_type=sa.Boolean(),
            comment="Pronounced idyll correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "labile",
            existing_type=sa.Boolean(),
            comment="Pronounced labile correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leviathan",
            existing_type=sa.Boolean(),
            comment="Pronounced leviathan correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "naive",
            existing_type=sa.Boolean(),
            comment="Pronounced naive correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "nausea",
            existing_type=sa.Boolean(),
            comment="Pronounced nausea correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "placebo",
            existing_type=sa.Boolean(),
            comment="Pronounced placebo correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "prelate",
            existing_type=sa.Boolean(),
            comment="Pronounced prelate correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "procreate",
            existing_type=sa.Boolean(),
            comment="Pronounced procreate correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "psalm",
            existing_type=sa.Boolean(),
            comment="Pronounced psalm correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "puerperal",
            existing_type=sa.Boolean(),
            comment="Pronounced puerperal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "quadruped",
            existing_type=sa.Boolean(),
            comment="Pronounced quadruped correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "radix",
            existing_type=sa.Boolean(),
            comment="Pronounced radix correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rarefy",
            existing_type=sa.Boolean(),
            comment="Pronounced rarefy correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sidereal",
            existing_type=sa.Boolean(),
            comment="Pronounced sidereal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "simile",
            existing_type=sa.Boolean(),
            comment="Pronounced simile correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtle",
            existing_type=sa.Boolean(),
            comment="Pronounced subtle correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "superfluous",
            existing_type=sa.Boolean(),
            comment="Pronounced superfluous correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "syncope",
            existing_type=sa.Boolean(),
            comment="Pronounced syncope correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thyme",
            existing_type=sa.Boolean(),
            comment="Pronounced thyme correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "topiary",
            existing_type=sa.Boolean(),
            comment="Pronounced topiary correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "zealot",
            existing_type=sa.Boolean(),
            comment="Pronounced zealot correctly (0 no, 1 yes)",
            existing_nullable=True,
        )

    with op.batch_alter_table("npiq", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment="Q1, delusions, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment="Q10, motor disturbance, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment="Q11, night-time behaviour, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment="Q12, appetite/eating, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment="Q2, hallucinations, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment="Q3, agitation/aggression, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment="Q4, depression/dysphoria, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment="Q5, anxiety, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment="Q6, elation/euphoria, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment="Q7, apathy/indifference, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment="Q8, disinhibition, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment="Q9, irritability/lability, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed1",
            existing_type=sa.Boolean(),
            comment="Q1, delusions, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed10",
            existing_type=sa.Boolean(),
            comment="Q10, motor disturbance, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed11",
            existing_type=sa.Boolean(),
            comment="Q11, night-time behaviour, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed12",
            existing_type=sa.Boolean(),
            comment="Q12, appetite/eating, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed2",
            existing_type=sa.Boolean(),
            comment="Q2, hallucinations, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed3",
            existing_type=sa.Boolean(),
            comment="Q3, agitation/aggression, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed4",
            existing_type=sa.Boolean(),
            comment="Q4, depression/dysphoria, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed5",
            existing_type=sa.Boolean(),
            comment="Q5, anxiety, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed6",
            existing_type=sa.Boolean(),
            comment="Q6, elation/euphoria, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed7",
            existing_type=sa.Boolean(),
            comment="Q7, apathy/indifference, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed8",
            existing_type=sa.Boolean(),
            comment="Q8, disinhibition, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed9",
            existing_type=sa.Boolean(),
            comment="Q9, irritability/lability, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity1",
            existing_type=sa.Integer(),
            comment="Q1, delusions, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity10",
            existing_type=sa.Integer(),
            comment="Q10, motor disturbance, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity11",
            existing_type=sa.Integer(),
            comment="Q11, night-time behaviour, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity12",
            existing_type=sa.Integer(),
            comment="Q12, appetite/eating, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity2",
            existing_type=sa.Integer(),
            comment="Q2, hallucinations, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity3",
            existing_type=sa.Integer(),
            comment="Q3, agitation/aggression, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity4",
            existing_type=sa.Integer(),
            comment="Q4, depression/dysphoria, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity5",
            existing_type=sa.Integer(),
            comment="Q5, anxiety, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity6",
            existing_type=sa.Integer(),
            comment="Q6, elation/euphoria, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity7",
            existing_type=sa.Integer(),
            comment="Q7, apathy/indifference, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity8",
            existing_type=sa.Integer(),
            comment="Q8, disinhibition, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity9",
            existing_type=sa.Integer(),
            comment="Q9, irritability/lability, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ors", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q_date",
            existing_type=sa.DATE(),
            comment="Session date",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_individual",
            existing_type=sa.Float(),
            comment="Individual rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_interpersonal",
            existing_type=sa.Float(),
            comment="Interpersonal rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_overall",
            existing_type=sa.Float(),
            comment="Overall rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_session",
            existing_type=sa.Integer(),
            comment="Session number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_social",
            existing_type=sa.Float(),
            comment="Social rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_who",
            existing_type=sa.Integer(),
            comment="Completed by",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_who_other",
            existing_type=sa.Text(),
            comment="Completed by other: who?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("panss", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1",
            existing_type=sa.Integer(),
            comment="G1: somatic concern (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g10",
            existing_type=sa.Integer(),
            comment="G10: disorientation (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g11",
            existing_type=sa.Integer(),
            comment="G11: poor attention (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g12",
            existing_type=sa.Integer(),
            comment="G12: lack of judgement/insight (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g13",
            existing_type=sa.Integer(),
            comment="G13: disturbance of volition (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g14",
            existing_type=sa.Integer(),
            comment="G14: poor impulse control (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g15",
            existing_type=sa.Integer(),
            comment="G15: preoccupation (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g16",
            existing_type=sa.Integer(),
            comment="G16: active social avoidance (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g2",
            existing_type=sa.Integer(),
            comment="G2: anxiety (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g3",
            existing_type=sa.Integer(),
            comment="G3: guilt feelings (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g4",
            existing_type=sa.Integer(),
            comment="G4: tension (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g5",
            existing_type=sa.Integer(),
            comment="G5: mannerisms/posturing (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g6",
            existing_type=sa.Integer(),
            comment="G6: depression (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g7",
            existing_type=sa.Integer(),
            comment="G7: motor retardation (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g8",
            existing_type=sa.Integer(),
            comment="G8: uncooperativeness (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g9",
            existing_type=sa.Integer(),
            comment="G9: unusual thought content (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "n1",
            existing_type=sa.Integer(),
            comment="N1: blunted affect (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n2",
            existing_type=sa.Integer(),
            comment="N2: emotional withdrawal (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n3",
            existing_type=sa.Integer(),
            comment="N3: poor rapport (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n4",
            existing_type=sa.Integer(),
            comment=(
                "N4: passive/apathetic social withdrawal (1 absent - 7"
                " extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n5",
            existing_type=sa.Integer(),
            comment=(
                "N5: difficulty in abstract thinking (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n6",
            existing_type=sa.Integer(),
            comment=(
                "N6: lack of spontaneity/conversation flow (1 absent - 7"
                " extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n7",
            existing_type=sa.Integer(),
            comment="N7: stereotyped thinking (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p1",
            existing_type=sa.Integer(),
            comment="P1: delusions (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p2",
            existing_type=sa.Integer(),
            comment="P2: conceptual disorganisation (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p3",
            existing_type=sa.Integer(),
            comment="P3: hallucinatory behaviour (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p4",
            existing_type=sa.Integer(),
            comment="P4: excitement (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p5",
            existing_type=sa.Integer(),
            comment="P5: grandiosity (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p6",
            existing_type=sa.Integer(),
            comment="P6: suspiciousness/persecution (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p7",
            existing_type=sa.Integer(),
            comment="P7: hostility (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("patient", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "address",
            existing_type=sa.Text(),
            comment="Address",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dob",
            existing_type=sa.DATE(),
            comment="Date of birth",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "forename",
            existing_type=sa.Unicode(length=255),
            comment="Forename",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gp",
            existing_type=sa.Text(),
            comment="General practitioner (GP)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="Primary key (patient ID) on the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other",
            existing_type=sa.Text(),
            comment="Other details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sex",
            existing_type=sa.String(length=1),
            comment="Sex (M, F, X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "surname",
            existing_type=sa.Unicode(length=255),
            comment="Surname",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("patient_idnum", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="Primary key on the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "idnum_value",
            existing_type=sa.BigInteger(),
            comment="The value of the ID number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="FK to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "which_idnum",
            existing_type=sa.Integer(),
            comment="Which of the server's ID numbers is this?",
            existing_nullable=False,
        )

    with op.batch_alter_table("pbq", schema=None) as batch_op:
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("pcl5", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (disturbing memories/thoughts/images) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10 (blaming) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (strong negative emotions) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (loss of interest in previously enjoyed activities) (0"
                " not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (feeling distant / cut off from people) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (feeling emotionally numb) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (irritable, angry and/or aggressive) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (risk-taking and/or self-harming behaviour) (0 not at all"
                " - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17 (super alert/on guard) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment="Q18 (jumpy/easily startled) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (difficulty concentrating) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (disturbing dreams) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment="Q20 (hard to sleep) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (reliving) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4 (upset at reminders) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (physical reactions to reminders) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (avoid activities/situations because they remind) (0 not"
                " at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (strong negative beliefs about self/others/world) (0 not"
                " at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("pclc", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (disturbing memories/thoughts/images) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (feeling distant/cut off from people) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (feeling emotionally numb) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (feeling future will be cut short) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13 (hard to sleep) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14 (irritable) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (difficulty concentrating) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="Q16 (super alert/on guard) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17 (jumpy/easily startled) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (disturbing dreams) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (reliving) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4 (upset at reminders) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (physical reactions to reminders) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (avoid activities/situations because they remind) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (loss of interest in previously enjoyed activities) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("pclm", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (disturbing memories/thoughts/images) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (feeling distant/cut off from people) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (feeling emotionally numb) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (feeling future will be cut short) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13 (hard to sleep) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14 (irritable) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (difficulty concentrating) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="Q16 (super alert/on guard) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17 (jumpy/easily startled) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (disturbing dreams) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (reliving) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4 (upset at reminders) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (physical reactions to reminders) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (avoid activities/situations because they remind) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (loss of interest in previously enjoyed activities) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("pcls", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "event",
            existing_type=sa.Text(),
            comment="Traumatic event",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eventdate",
            existing_type=sa.Text(),
            comment="Date of traumatic event (free text)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (disturbing memories/thoughts/images) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (feeling distant/cut off from people) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (feeling emotionally numb) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (feeling future will be cut short) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13 (hard to sleep) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14 (irritable) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (difficulty concentrating) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="Q16 (super alert/on guard) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17 (jumpy/easily startled) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (disturbing dreams) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (reliving) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4 (upset at reminders) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (physical reactions to reminders) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (avoid activities/situations because they remind) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (loss of interest in previously enjoyed activities) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("pdss", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, frequency (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, distressing during (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, anxiety about panic (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, places or situations avoided (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, activities avoided (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6, interference with responsibilities (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, interference with social life (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("perinatal_poem", schema=None) as batch_op:
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("photo", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment="Description of the photograph",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "photo_blobid",
            existing_type=sa.Integer(),
            comment=(
                "ID of the BLOB (foreign key to blobs.id, given matching"
                " device and current/frozen record status)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rotation",
            existing_type=sa.Integer(),
            comment=(
                "Rotation (clockwise, in degrees) to be applied for viewing"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("photosequence", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "sequence_description",
            existing_type=sa.Text(),
            comment="Description of the sequence of photographs",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("photosequence_photos", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment="Description of the photograph",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "photo_blobid",
            existing_type=sa.Integer(),
            comment=(
                "ID of the BLOB (foreign key to blobs.id, given matching"
                " device and current/frozen record status)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "photosequence_id",
            existing_type=sa.Integer(),
            comment="Tablet FK to photosequence",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rotation",
            existing_type=sa.Integer(),
            comment=(
                "(DEFUNCT COLUMN) Rotation (clockwise, in degrees) to be"
                " applied for viewing"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "seqnum",
            existing_type=sa.Integer(),
            comment=(
                "Sequence number of this photo (consistently 1-based as of"
                " 2018-12-01)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("phq15", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=(
                "Q1 (stomach pain) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (breathless) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11 (sex) (0 not bothered at all - 2 bothered a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (constipation/diarrhoea) (0 not bothered at all - 2"
                " bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (nausea/indigestion) (0 not bothered at all - 2 bothered"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14 (energy) (0 not bothered at all - 2 bothered a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment="Q15 (sleep) (0 not bothered at all - 2 bothered a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2 (back pain) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (limb/joint pain) (0 not bothered at all - 2 bothered a"
                " lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (F - menstrual) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (headaches) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (chest pain) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (dizziness) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8 (fainting) (0 not bothered at all - 2 bothered a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (palpitations) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("phq9", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1 (anhedonia) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (difficulty in activities) (0 not difficult at all - 3"
                " extremely difficult)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (mood) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (sleep) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4 (energy) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5 (appetite) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (self-esteem/guilt) (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7 (concentration) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8 (psychomotor) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9 (death/self-harm) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("progressnote", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "location",
            existing_type=sa.Text(),
            comment="Location",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "note",
            existing_type=sa.Text(),
            comment="Clinical note",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("pswq", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, OK if not enough time [REVERSE SCORE] (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, never worry [REVERSE SCORE] (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11, if nothing more to do, I do not worry [REVERSE SCORE]"
                " (1-5)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, lifelong worrier (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13, have been worrying (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14, when start worrying cannot stop (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment="Q15, worry all the time (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="Q16, worry about projects until done (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, worries overwhelm (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, do not tend to worry [REVERSE SCORE] (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, many situations make me worry (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, cannot help worrying (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, worry under pressure (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, always worrying (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, easily dismiss worries [REVERSE SCORE] (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, finish then worry about next thing (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("psychiatricclerking", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("pt_satis", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bad",
            existing_type=sa.Text(),
            comment="What could be improved?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "good",
            existing_type=sa.Text(),
            comment="What has been good?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment="Rating (0 very poor - 4 excellent)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("qolbasic", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rs",
            existing_type=sa.Float(),
            comment=(
                "Rating scale (QoL * 100). Prompt: Mark the point on the scale"
                " [0-100] that you feel best illustrates your current quality"
                " of life."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tto",
            existing_type=sa.Float(),
            comment=(
                "Time trade-off (QoL * 10). Prompt: ... Indicate... the number"
                " of years in full health [0-10] that you think is of equal"
                " value to 10 years in your current health state."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("qolsg", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_chosen",
            existing_type=sa.String(length=6),
            comment=(
                "Category chosen: high (QoL > 1) medium (0 <= QoL <= 1) low"
                " (QoL < 0)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_responded",
            existing_type=sa.Integer(),
            comment="Responded to category choice? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Time category was chosen (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Time categories were offered (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_fixed_option",
            existing_type=sa.String(length=7),
            comment="Fixed option in gamble (current, healthy, dead)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_lottery_on_left",
            existing_type=sa.Integer(),
            comment="Gamble: lottery shown on the left (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_lottery_option_p",
            existing_type=sa.String(length=7),
            comment=(
                "Gamble: option corresponding to p  (current, healthy, dead)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_lottery_option_q",
            existing_type=sa.String(length=7),
            comment=(
                "Gamble: option corresponding to q  (current, healthy, dead)"
                " (q = 1 - p)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_p",
            existing_type=sa.Float(),
            comment="Final value of p",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_responded",
            existing_type=sa.Integer(),
            comment="Gamble was responded to? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Time subject responded to gamble (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="Time gamble was offered (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_starting_p",
            existing_type=sa.Float(),
            comment="Gamble: starting value of p",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "utility",
            existing_type=sa.Float(),
            comment="Calculated utility, h",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("rand36", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1 (general health) (1 excellent - 5 poor)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=(
                "Q10 (Walking several blocks) (1 limited a lot - 3 not limited"
                " at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (Walking one block) (1 limited a lot - 3 not limited at"
                " all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (Bathing or dressing yourself) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (physical health: Cut down work/other activities) (1 yes,"
                " 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=(
                "Q14 (physical health: Accomplished less than would like) (1"
                " yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=(
                "Q15 (physical health: Were limited in the kind of work or"
                " other activities) (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=(
                "Q16 (physical health: Had difficulty performing the work or"
                " other activities) (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=(
                "Q17 (emotional problems: Cut down work/other activities) (1"
                " yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=(
                "Q18 (emotional problems: Accomplished less than would like)"
                " (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=(
                "Q19 (emotional problems: Didn't do work or other activities"
                " as carefully as usual) (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (health cf. 1y ago) (1 much better - 5 much worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=(
                "Q20 (past 4 weeks, to what extent physical health/emotional"
                " problems interfered with social activity) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=(
                "Q21 (past 4 weeks, how much pain (1 none - 6 very severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=(
                "Q22 (past 4 weeks, pain interfered with normal activity (1"
                " not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=(
                "Q23 (past 4 weeks: Did you feel full of pep?) (1 all of the"
                " time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=(
                "Q24 (past 4 weeks: Have you been a very nervous person?) (1"
                " all of the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=(
                "Q25 (past 4 weeks: Have you felt so down in the dumps that"
                " nothing could cheer you up?) (1 all of the time - 6 none of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=(
                "Q26 (past 4 weeks: Have you felt calm and peaceful?) (1 all"
                " of the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=(
                "Q27 (past 4 weeks: Did you have a lot of energy?) (1 all of"
                " the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=(
                "Q28 (past 4 weeks: Have you felt downhearted and blue?) (1"
                " all of the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=(
                "Q29 (past 4 weeks: Did you feel worn out?) (1 all of the time"
                " - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=(
                "Q3 (Vigorous activities) (1 limited a lot - 3 not limited at"
                " all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment=(
                "Q30 (past 4 weeks: Have you been a happy person?) (1 all of"
                " the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q31",
            existing_type=sa.Integer(),
            comment=(
                "Q31 (past 4 weeks: Did you feel tired?) (1 all of the time -"
                " 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q32",
            existing_type=sa.Integer(),
            comment=(
                "Q32 (past 4 weeks, how much of the time has physical"
                " health/emotional problems interfered with social activities"
                " (1 all of the time - 5 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q33",
            existing_type=sa.Integer(),
            comment=(
                "Q33 (how true/false: I seem to get sick a little easier than"
                " other people) (1 definitely true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q34",
            existing_type=sa.Integer(),
            comment=(
                "Q34 (how true/false: I am as healthy as anybody I know) (1"
                " definitely true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q35",
            existing_type=sa.Integer(),
            comment=(
                "Q35 (how true/false: I expect my health to get worse) (1"
                " definitely true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q36",
            existing_type=sa.Integer(),
            comment=(
                "Q36 (how true/false: My health is excellent) (1 definitely"
                " true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (Moderate activities) (1 limited a lot - 3 not limited at"
                " all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=(
                "Q5 (Lifting or carrying groceries) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (Climbing several flights of stairs) (1 limited a lot - 3"
                " not limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (Climbing one flight of stairs) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (Bending, kneeling, or stooping) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (Walking more than a mile) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ref_satis_gen", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bad",
            existing_type=sa.Text(),
            comment="What could be improved?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "good",
            existing_type=sa.Text(),
            comment="What has been good?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment="Rating (0 very poor - 4 excellent)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ref_satis_spec", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bad",
            existing_type=sa.Text(),
            comment="What could be improved?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "good",
            existing_type=sa.Text(),
            comment="What has been good?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment="Rating (0 very poor - 4 excellent)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("slums", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "alert",
            existing_type=sa.Integer(),
            comment="Is the patient alert? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clockpicture_blobid",
            existing_type=sa.Integer(),
            comment="BLOB ID of clock picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "highschooleducation",
            existing_type=sa.Integer(),
            comment=(
                "Does that patient have at least a high-school level of"
                " education? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1 (day) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10a",
            existing_type=sa.Integer(),
            comment="Q10a (X in triangle) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10b",
            existing_type=sa.Integer(),
            comment="Q10b (biggest figure) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11a",
            existing_type=sa.Integer(),
            comment="Q11a (story - name) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11b",
            existing_type=sa.Integer(),
            comment="Q11b (story - occupation) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11c",
            existing_type=sa.Integer(),
            comment="Q11c (story - back to work) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11d",
            existing_type=sa.Integer(),
            comment="Q11d (story - state) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (year) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (state) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5a",
            existing_type=sa.Integer(),
            comment="Q5a (money spent) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5b",
            existing_type=sa.Integer(),
            comment="Q5b (money left) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6 (animal naming) (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7a",
            existing_type=sa.Integer(),
            comment="Q7a (recall apple) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7b",
            existing_type=sa.Integer(),
            comment="Q7b (recall pen) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7c",
            existing_type=sa.Integer(),
            comment="Q7c (recall tie) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7d",
            existing_type=sa.Integer(),
            comment="Q7d (recall house) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7e",
            existing_type=sa.Integer(),
            comment="Q7e (recall car) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8b",
            existing_type=sa.Integer(),
            comment="Q8b (reverse 648) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8c",
            existing_type=sa.Integer(),
            comment="Q8c (reverse 8537) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9a",
            existing_type=sa.Integer(),
            comment="Q9a (clock - hour markers) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9b",
            existing_type=sa.Integer(),
            comment="Q9b (clock - time) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "shapespicture_blobid",
            existing_type=sa.Integer(),
            comment="BLOB ID of shapes picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("smast", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment="Q1: believe you are a normal drinker (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment="Q10: sought help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment="Q11: hospitalized (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment="Q12: arrested for drink-driving (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment="Q13: arrested for other drunken behaviour (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment="Q2: near relative worries/complains (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment="Q3: feel guilty (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=(
                "Q4: friends/relative think you are a normal drinker (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment="Q5: stop when you want to (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment="Q6: ever attended Alcoholics Anonymous (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment="Q7: problems with close relative (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment="Q8: trouble at work (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment="Q9: neglected obligations for >=2 days (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("srs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q_approach",
            existing_type=sa.Float(),
            comment="Rating for therapist's approach (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_date",
            existing_type=sa.DATE(),
            comment="Session date",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_goals",
            existing_type=sa.Float(),
            comment="Rating for topics discussed (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_overall",
            existing_type=sa.Float(),
            comment="Overall rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_relationship",
            existing_type=sa.Float(),
            comment=(
                "Rating of patient-therapist relationship (0-10, 10 better)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_session",
            existing_type=sa.Integer(),
            comment="Session number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("swemwbs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1 (optimistic) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (useful) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (relaxed) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (interested in other people) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5 (energy) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (dealing with problems well) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (thinking clearly) (1 none of the time - 5 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("wemwbs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1 (optimistic) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10 (confident) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=(
                "Q11 (able to make up my own mind) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=(
                "Q12 (feeling loved) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=(
                "Q13 (interested in new things) (1 none of the time - 5 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14 (cheerful) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2 (useful) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3 (relaxed) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=(
                "Q4 (interested in other people) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5 (energy) (1 none of the time - 5 all of the time)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=(
                "Q6 (dealing with problems well) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=(
                "Q7 (thinking clearly) (1 none of the time - 5 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=(
                "Q8 (feeling good about myself) (1 none of the time - 5 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=(
                "Q9 (feeling close to others) (1 none of the time - 5 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("wsas", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, work (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, home management (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, social leisure (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, private leisure (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, relationships (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "retired_etc",
            existing_type=sa.Boolean(),
            comment=(
                "Retired or choose not to have job for reason unrelated to"
                " problem"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ybocs", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, obsessions: time (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, compulsions: control (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, insight (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, avoidance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment="Q13, indecisiveness (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment="Q14, overvalued responsibility (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment="Q15, slowness (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment="Q16, doubting (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment="Q17, global severity (0-6, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment="Q18, global improvement (0-6, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment="Q19, reliability (0-3, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1b",
            existing_type=sa.Integer(),
            comment=(
                "Q1b, obsessions: obsession-free interval (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment="Q2, obsessions: interference (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, obsessions: distress (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, obsessions: resistance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, obsessions: control (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, compulsions: time (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6b",
            existing_type=sa.Integer(),
            comment=(
                "Q6b, compulsions: compulsion-free interval (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, compulsions: interference (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, compulsions: distress (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, compulsions: resistance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_avoidance_1",
            existing_type=sa.Text(),
            comment="Target symptoms: avoidance 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_avoidance_2",
            existing_type=sa.Text(),
            comment="Target symptoms: avoidance 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_avoidance_3",
            existing_type=sa.Text(),
            comment="Target symptoms: avoidance 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_compulsion_1",
            existing_type=sa.Text(),
            comment="Target symptoms: compulsion 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_compulsion_2",
            existing_type=sa.Text(),
            comment="Target symptoms: compulsion 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_compulsion_3",
            existing_type=sa.Text(),
            comment="Target symptoms: compulsion 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_obsession_1",
            existing_type=sa.Text(),
            comment="Target symptoms: obsession 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_obsession_2",
            existing_type=sa.Text(),
            comment="Target symptoms: obsession 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_obsession_3",
            existing_type=sa.Text(),
            comment="Target symptoms: obsession 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("ybocssc", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_current",
            existing_type=sa.Boolean(),
            comment="com_arranging_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_detail",
            existing_type=sa.Text(),
            comment="com_arranging_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_past",
            existing_type=sa.Boolean(),
            comment="com_arranging_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_principal",
            existing_type=sa.Boolean(),
            comment="com_arranging_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_locks_appliances_current",
            existing_type=sa.Boolean(),
            comment="com_checking_locks_appliances (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_locks_appliances_past",
            existing_type=sa.Boolean(),
            comment="com_checking_locks_appliances (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_locks_appliances_principal",
            existing_type=sa.Boolean(),
            comment="com_checking_locks_appliances (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_no_mistake_current",
            existing_type=sa.Boolean(),
            comment="com_checking_no_mistake (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_no_mistake_past",
            existing_type=sa.Boolean(),
            comment="com_checking_no_mistake (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_no_mistake_principal",
            existing_type=sa.Boolean(),
            comment="com_checking_no_mistake (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_others_current",
            existing_type=sa.Boolean(),
            comment="com_checking_not_harm_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_others_past",
            existing_type=sa.Boolean(),
            comment="com_checking_not_harm_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_others_principal",
            existing_type=sa.Boolean(),
            comment="com_checking_not_harm_others (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_self_current",
            existing_type=sa.Boolean(),
            comment="com_checking_not_harm_self (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_self_past",
            existing_type=sa.Boolean(),
            comment="com_checking_not_harm_self (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_self_principal",
            existing_type=sa.Boolean(),
            comment="com_checking_not_harm_self (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_nothing_bad_happens_current",
            existing_type=sa.Boolean(),
            comment="com_checking_nothing_bad_happens (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_nothing_bad_happens_past",
            existing_type=sa.Boolean(),
            comment="com_checking_nothing_bad_happens (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_nothing_bad_happens_principal",
            existing_type=sa.Boolean(),
            comment="com_checking_nothing_bad_happens (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_current",
            existing_type=sa.Boolean(),
            comment="com_checking_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_detail",
            existing_type=sa.Text(),
            comment="com_checking_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_past",
            existing_type=sa.Boolean(),
            comment="com_checking_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_principal",
            existing_type=sa.Boolean(),
            comment="com_checking_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_somatic_current",
            existing_type=sa.Boolean(),
            comment="com_checking_somatic (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_somatic_past",
            existing_type=sa.Boolean(),
            comment="com_checking_somatic (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_somatic_principal",
            existing_type=sa.Boolean(),
            comment="com_checking_somatic (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_cleaning_items_current",
            existing_type=sa.Boolean(),
            comment="com_cleaning_cleaning_items (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_cleaning_items_past",
            existing_type=sa.Boolean(),
            comment="com_cleaning_cleaning_items (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_cleaning_items_principal",
            existing_type=sa.Boolean(),
            comment="com_cleaning_cleaning_items (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_handwashing_current",
            existing_type=sa.Boolean(),
            comment="com_cleaning_handwashing (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_handwashing_past",
            existing_type=sa.Boolean(),
            comment="com_cleaning_handwashing (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_handwashing_principal",
            existing_type=sa.Boolean(),
            comment="com_cleaning_handwashing (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_contaminant_avoidance_current",
            existing_type=sa.Boolean(),
            comment=(
                "com_cleaning_other_contaminant_avoidance (current symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_contaminant_avoidance_past",
            existing_type=sa.Boolean(),
            comment="com_cleaning_other_contaminant_avoidance (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_contaminant_avoidance_principal",
            existing_type=sa.Boolean(),
            comment=(
                "com_cleaning_other_contaminant_avoidance (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_current",
            existing_type=sa.Boolean(),
            comment="com_cleaning_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_detail",
            existing_type=sa.Text(),
            comment="com_cleaning_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_past",
            existing_type=sa.Boolean(),
            comment="com_cleaning_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_principal",
            existing_type=sa.Boolean(),
            comment="com_cleaning_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_toileting_current",
            existing_type=sa.Boolean(),
            comment="com_cleaning_toileting (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_toileting_past",
            existing_type=sa.Boolean(),
            comment="com_cleaning_toileting (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_toileting_principal",
            existing_type=sa.Boolean(),
            comment="com_cleaning_toileting (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_current",
            existing_type=sa.Boolean(),
            comment="com_counting_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_detail",
            existing_type=sa.Text(),
            comment="com_counting_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_past",
            existing_type=sa.Boolean(),
            comment="com_counting_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_principal",
            existing_type=sa.Boolean(),
            comment="com_counting_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_current",
            existing_type=sa.Boolean(),
            comment="com_hoarding_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_detail",
            existing_type=sa.Text(),
            comment="com_hoarding_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_past",
            existing_type=sa.Boolean(),
            comment="com_hoarding_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_principal",
            existing_type=sa.Boolean(),
            comment="com_hoarding_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_blink_stare_current",
            existing_type=sa.Boolean(),
            comment="com_misc_blink_stare (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_blink_stare_past",
            existing_type=sa.Boolean(),
            comment="com_misc_blink_stare (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_blink_stare_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_blink_stare (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_eating_ritual_current",
            existing_type=sa.Boolean(),
            comment="com_misc_eating_ritual (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_eating_ritual_past",
            existing_type=sa.Boolean(),
            comment="com_misc_eating_ritual (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_eating_ritual_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_eating_ritual (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_lists_current",
            existing_type=sa.Boolean(),
            comment="com_misc_lists (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_lists_past",
            existing_type=sa.Boolean(),
            comment="com_misc_lists (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_lists_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_lists (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_mental_rituals_current",
            existing_type=sa.Boolean(),
            comment="com_misc_mental_rituals (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_mental_rituals_past",
            existing_type=sa.Boolean(),
            comment="com_misc_mental_rituals (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_mental_rituals_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_mental_rituals (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_current",
            existing_type=sa.Boolean(),
            comment="com_misc_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_detail",
            existing_type=sa.Text(),
            comment="com_misc_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_past",
            existing_type=sa.Boolean(),
            comment="com_misc_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_others_current",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_harm_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_others_past",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_harm_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_others_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_harm_others (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_self_current",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_harm_self (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_self_past",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_harm_self (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_self_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_harm_self (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_terrible_current",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_terrible (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_terrible_past",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_terrible (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_terrible_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_prevent_terrible (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_self_harm_current",
            existing_type=sa.Boolean(),
            comment="com_misc_self_harm (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_self_harm_past",
            existing_type=sa.Boolean(),
            comment="com_misc_self_harm (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_self_harm_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_self_harm (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_superstitious_current",
            existing_type=sa.Boolean(),
            comment="com_misc_superstitious (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_superstitious_past",
            existing_type=sa.Boolean(),
            comment="com_misc_superstitious (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_superstitious_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_superstitious (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_tell_ask_current",
            existing_type=sa.Boolean(),
            comment="com_misc_tell_ask (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_tell_ask_past",
            existing_type=sa.Boolean(),
            comment="com_misc_tell_ask (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_tell_ask_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_tell_ask (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_touch_current",
            existing_type=sa.Boolean(),
            comment="com_misc_touch (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_touch_past",
            existing_type=sa.Boolean(),
            comment="com_misc_touch (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_touch_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_touch (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_trichotillomania_current",
            existing_type=sa.Boolean(),
            comment="com_misc_trichotillomania (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_trichotillomania_past",
            existing_type=sa.Boolean(),
            comment="com_misc_trichotillomania (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_trichotillomania_principal",
            existing_type=sa.Boolean(),
            comment="com_misc_trichotillomania (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_current",
            existing_type=sa.Boolean(),
            comment="com_repeat_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_detail",
            existing_type=sa.Text(),
            comment="com_repeat_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_past",
            existing_type=sa.Boolean(),
            comment="com_repeat_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_principal",
            existing_type=sa.Boolean(),
            comment="com_repeat_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_reread_rewrite_current",
            existing_type=sa.Boolean(),
            comment="com_repeat_reread_rewrite (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_reread_rewrite_past",
            existing_type=sa.Boolean(),
            comment="com_repeat_reread_rewrite (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_reread_rewrite_principal",
            existing_type=sa.Boolean(),
            comment="com_repeat_reread_rewrite (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_routine_current",
            existing_type=sa.Boolean(),
            comment="com_repeat_routine (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_routine_past",
            existing_type=sa.Boolean(),
            comment="com_repeat_routine (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_routine_principal",
            existing_type=sa.Boolean(),
            comment="com_repeat_routine (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "obs_aggressive_accident_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_accident (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_accident_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_accident (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_accident_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_accident (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_embarrassing_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_embarrassing (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_embarrassing_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_embarrassing (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_embarrassing_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_embarrassing (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_others_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_harm_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_others_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_harm_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_others_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_harm_others (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_self_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_harm_self (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_self_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_harm_self (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_self_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_harm_self (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_imagery_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_imagery (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_imagery_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_imagery (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_imagery_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_imagery (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_impulses_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_impulses (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_impulses_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_impulses (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_impulses_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_impulses (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_obscenities_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_obscenities (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_obscenities_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_obscenities (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_obscenities_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_obscenities (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_detail",
            existing_type=sa.Text(),
            comment="obs_aggressive_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_responsible_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_responsible (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_responsible_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_responsible (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_responsible_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_responsible (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_steal_current",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_steal (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_steal_past",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_steal (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_steal_principal",
            existing_type=sa.Boolean(),
            comment="obs_aggressive_steal (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_animals_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_animals (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_animals_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_animals (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_animals_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_animals (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_bodily_waste_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_bodily_waste (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_bodily_waste_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_bodily_waste (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_bodily_waste_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_bodily_waste (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_dirt_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_dirt (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_dirt_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_dirt (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_dirt_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_dirt (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_environmental_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_environmental (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_environmental_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_environmental (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_environmental_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_environmental (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_feeling_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_feeling (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_feeling_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_feeling (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_feeling_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_feeling (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_household_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_household (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_household_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_household (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_household_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_household (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_ill_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_ill (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_ill_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_ill (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_ill_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_ill (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_detail",
            existing_type=sa.Text(),
            comment="obs_contamination_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_others_ill_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_others_ill (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_others_ill_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_others_ill (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_others_ill_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_others_ill (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_sticky_current",
            existing_type=sa.Boolean(),
            comment="obs_contamination_sticky (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_sticky_past",
            existing_type=sa.Boolean(),
            comment="obs_contamination_sticky (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_sticky_principal",
            existing_type=sa.Boolean(),
            comment="obs_contamination_sticky (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_current",
            existing_type=sa.Boolean(),
            comment="obs_hoarding_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_detail",
            existing_type=sa.Text(),
            comment="obs_hoarding_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_past",
            existing_type=sa.Boolean(),
            comment="obs_hoarding_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_principal",
            existing_type=sa.Boolean(),
            comment="obs_hoarding_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_bothered_sounds_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_bothered_sounds (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_bothered_sounds_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_bothered_sounds (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_bothered_sounds_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_bothered_sounds (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_colours_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_colours (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_colours_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_colours (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_colours_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_colours (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_losing_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_losing (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_losing_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_losing (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_losing_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_losing (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_not_saying_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_not_saying (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_not_saying_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_not_saying (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_not_saying_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_not_saying (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_saying_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_saying (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_saying_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_saying (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_saying_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_fear_saying (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_nonviolent_images_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_intrusive_nonviolent_images (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_nonviolent_images_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_intrusive_nonviolent_images (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_nonviolent_images_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_intrusive_nonviolent_images (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_sounds_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_intrusive_sounds (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_sounds_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_intrusive_sounds (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_sounds_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_intrusive_sounds (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_know_remember_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_know_remember (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_know_remember_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_know_remember (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_know_remember_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_know_remember (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_numbers_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_numbers (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_numbers_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_numbers (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_numbers_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_numbers (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_detail",
            existing_type=sa.Text(),
            comment="obs_misc_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_superstitious_current",
            existing_type=sa.Boolean(),
            comment="obs_misc_superstitious (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_superstitious_past",
            existing_type=sa.Boolean(),
            comment="obs_misc_superstitious (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_superstitious_principal",
            existing_type=sa.Boolean(),
            comment="obs_misc_superstitious (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_morality_current",
            existing_type=sa.Boolean(),
            comment="obs_religious_morality (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_morality_past",
            existing_type=sa.Boolean(),
            comment="obs_religious_morality (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_morality_principal",
            existing_type=sa.Boolean(),
            comment="obs_religious_morality (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_current",
            existing_type=sa.Boolean(),
            comment="obs_religious_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_detail",
            existing_type=sa.Text(),
            comment="obs_religious_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_past",
            existing_type=sa.Boolean(),
            comment="obs_religious_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_principal",
            existing_type=sa.Boolean(),
            comment="obs_religious_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_sacrilege_current",
            existing_type=sa.Boolean(),
            comment="obs_religious_sacrilege (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_sacrilege_past",
            existing_type=sa.Boolean(),
            comment="obs_religious_sacrilege (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_sacrilege_principal",
            existing_type=sa.Boolean(),
            comment="obs_religious_sacrilege (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_children_incest_current",
            existing_type=sa.Boolean(),
            comment="obs_sexual_children_incest (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_children_incest_past",
            existing_type=sa.Boolean(),
            comment="obs_sexual_children_incest (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_children_incest_principal",
            existing_type=sa.Boolean(),
            comment="obs_sexual_children_incest (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_forbidden_current",
            existing_type=sa.Boolean(),
            comment="obs_sexual_forbidden (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_forbidden_past",
            existing_type=sa.Boolean(),
            comment="obs_sexual_forbidden (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_forbidden_principal",
            existing_type=sa.Boolean(),
            comment="obs_sexual_forbidden (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_homosexuality_current",
            existing_type=sa.Boolean(),
            comment="obs_sexual_homosexuality (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_homosexuality_past",
            existing_type=sa.Boolean(),
            comment="obs_sexual_homosexuality (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_homosexuality_principal",
            existing_type=sa.Boolean(),
            comment="obs_sexual_homosexuality (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_current",
            existing_type=sa.Boolean(),
            comment="obs_sexual_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_detail",
            existing_type=sa.Text(),
            comment="obs_sexual_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_past",
            existing_type=sa.Boolean(),
            comment="obs_sexual_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_principal",
            existing_type=sa.Boolean(),
            comment="obs_sexual_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_to_others_current",
            existing_type=sa.Boolean(),
            comment="obs_sexual_to_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_to_others_past",
            existing_type=sa.Boolean(),
            comment="obs_sexual_to_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_to_others_principal",
            existing_type=sa.Boolean(),
            comment="obs_sexual_to_others (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_appearance_current",
            existing_type=sa.Boolean(),
            comment="obs_somatic_appearance (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_appearance_past",
            existing_type=sa.Boolean(),
            comment="obs_somatic_appearance (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_appearance_principal",
            existing_type=sa.Boolean(),
            comment="obs_somatic_appearance (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_illness_current",
            existing_type=sa.Boolean(),
            comment="obs_somatic_illness (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_illness_past",
            existing_type=sa.Boolean(),
            comment="obs_somatic_illness (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_illness_principal",
            existing_type=sa.Boolean(),
            comment="obs_somatic_illness (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_current",
            existing_type=sa.Boolean(),
            comment="obs_somatic_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_detail",
            existing_type=sa.Text(),
            comment="obs_somatic_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_past",
            existing_type=sa.Boolean(),
            comment="obs_somatic_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_principal",
            existing_type=sa.Boolean(),
            comment="obs_somatic_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_with_magical_current",
            existing_type=sa.Boolean(),
            comment="obs_symmetry_with_magical (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_with_magical_past",
            existing_type=sa.Boolean(),
            comment="obs_symmetry_with_magical (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_with_magical_principal",
            existing_type=sa.Boolean(),
            comment="obs_symmetry_with_magical (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_without_magical_current",
            existing_type=sa.Boolean(),
            comment="obs_symmetry_without_magical (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_without_magical_past",
            existing_type=sa.Boolean(),
            comment="obs_symmetry_without_magical (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_without_magical_principal",
            existing_type=sa.Boolean(),
            comment="obs_symmetry_without_magical (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table("zbi12", schema=None) as batch_op:
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment="(SERVER) CamCOPS version number of the uploading device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of group to which this record belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment="(SERVER) Record manually erased (content destroyed)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that erased this row manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment="(SERVER/TABLET) Record-specific preservation pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment="(SERVER) PK of predecessor record, prior to modification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment="(SERVER) Date/time this row was added (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment="(TASK) Primary key (task ID) on the tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment="(TASK) Foreign key to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment="Q1, insufficient time for self (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment="Q10, uncertain (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment="Q11, should do more (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment="Q12, could care better (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=(
                "Q2, stressed with other responsibilities (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment="Q3, angry (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment="Q4, other relationships affected (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment="Q5, strained (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment="Q6, health suffered (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment="Q7, insufficient privacy (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment="Q8, social life suffered (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment="Q9, lost control (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment="(RESPONDENT) Respondent's relationship to patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )

    # ### end Alembic commands ###


# noinspection PyPep8,PyTypeChecker
def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table("zbi12", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, lost control (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, social life suffered (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, insufficient privacy (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, health suffered (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, strained (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, other relationships affected (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, angry (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, stressed with other responsibilities (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12, could care better (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11, should do more (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, uncertain (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, insufficient time for self (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ybocssc", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "obs_symmetry_without_magical_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_symmetry_without_magical (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_without_magical_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_symmetry_without_magical (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_without_magical_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_symmetry_without_magical (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_with_magical_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_symmetry_with_magical (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_with_magical_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_symmetry_with_magical (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_symmetry_with_magical_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_symmetry_with_magical (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="obs_somatic_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_illness_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_illness (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_illness_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_illness (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_illness_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_illness (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_appearance_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_appearance (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_appearance_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_appearance (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_somatic_appearance_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_somatic_appearance (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_to_others_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_to_others (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_to_others_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_to_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_to_others_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_to_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="obs_sexual_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_homosexuality_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_homosexuality (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_homosexuality_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_homosexuality (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_homosexuality_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_homosexuality (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_forbidden_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_forbidden (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_forbidden_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_forbidden (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_forbidden_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_forbidden (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_children_incest_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_children_incest (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_children_incest_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_children_incest (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_sexual_children_incest_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_sexual_children_incest (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_sacrilege_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_sacrilege (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_sacrilege_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_sacrilege (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_sacrilege_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_sacrilege (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="obs_religious_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_morality_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_morality (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_morality_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_morality (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_religious_morality_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_religious_morality (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_superstitious_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_superstitious (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_superstitious_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_superstitious (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_superstitious_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_superstitious (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="obs_misc_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_numbers_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_numbers (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_numbers_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_numbers (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_numbers_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_numbers (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_know_remember_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_know_remember (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_know_remember_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_know_remember (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_know_remember_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_know_remember (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_sounds_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_intrusive_sounds (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_sounds_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_intrusive_sounds (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_sounds_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_intrusive_sounds (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_nonviolent_images_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_misc_intrusive_nonviolent_images (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_nonviolent_images_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_misc_intrusive_nonviolent_images (past symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_intrusive_nonviolent_images_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_misc_intrusive_nonviolent_images (current symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_saying_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_saying (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_saying_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_saying (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_saying_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_saying (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_not_saying_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_not_saying (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_not_saying_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_not_saying (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_not_saying_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_not_saying (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_losing_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_losing (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_losing_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_losing (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_fear_losing_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_fear_losing (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_colours_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_colours (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_colours_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_colours (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_colours_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_colours (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_bothered_sounds_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_bothered_sounds (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_bothered_sounds_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_bothered_sounds (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_misc_bothered_sounds_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_misc_bothered_sounds (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_hoarding_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_hoarding_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="obs_hoarding_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_hoarding_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_hoarding_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_sticky_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_sticky (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_sticky_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_sticky (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_sticky_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_sticky (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_others_ill_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_contamination_others_ill (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_others_ill_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_others_ill (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_others_ill_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_others_ill (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="obs_contamination_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_ill_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_ill (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_ill_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_ill (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_ill_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_ill (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_household_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_household (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_household_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_household (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_household_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_household (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_feeling_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_feeling (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_feeling_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_feeling (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_feeling_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_feeling (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_environmental_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_contamination_environmental (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_environmental_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_environmental (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_environmental_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_contamination_environmental (current symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_dirt_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_dirt (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_dirt_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_dirt (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_dirt_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_dirt (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_bodily_waste_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_contamination_bodily_waste (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_bodily_waste_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_bodily_waste (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_bodily_waste_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "obs_contamination_bodily_waste (current symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_animals_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_animals (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_animals_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_animals (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_contamination_animals_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_contamination_animals (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_steal_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_steal (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_steal_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_steal (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_steal_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_steal (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_responsible_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_responsible (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_responsible_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_responsible (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_responsible_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_responsible (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="obs_aggressive_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_obscenities_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_obscenities (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_obscenities_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_obscenities (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_obscenities_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_obscenities (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_impulses_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_impulses (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_impulses_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_impulses (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_impulses_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_impulses (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_imagery_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_imagery (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_imagery_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_imagery (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_imagery_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_imagery (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_self_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_harm_self (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_self_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_harm_self (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_self_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_harm_self (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_others_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_harm_others (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_others_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_harm_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_harm_others_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_harm_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_embarrassing_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_embarrassing (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_embarrassing_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_embarrassing (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_embarrassing_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_embarrassing (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_accident_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_accident (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_accident_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_accident (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obs_aggressive_accident_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="obs_aggressive_accident (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_routine_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_routine (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_routine_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_routine (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_routine_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_routine (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_reread_rewrite_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_reread_rewrite (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_reread_rewrite_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_reread_rewrite (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_reread_rewrite_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_reread_rewrite (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="com_repeat_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_repeat_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_repeat_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_trichotillomania_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_trichotillomania (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_trichotillomania_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_trichotillomania (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_trichotillomania_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_trichotillomania (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_touch_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_touch (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_touch_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_touch (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_touch_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_touch (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_tell_ask_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_tell_ask (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_tell_ask_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_tell_ask (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_tell_ask_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_tell_ask (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_superstitious_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_superstitious (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_superstitious_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_superstitious (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_superstitious_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_superstitious (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_self_harm_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_self_harm (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_self_harm_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_self_harm (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_self_harm_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_self_harm (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_terrible_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_terrible (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_terrible_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_terrible (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_terrible_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_terrible (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_self_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_harm_self (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_self_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_harm_self (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_self_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_harm_self (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_others_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_misc_prevent_harm_others (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_others_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_harm_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_prevent_harm_others_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_prevent_harm_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="com_misc_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_mental_rituals_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_mental_rituals (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_mental_rituals_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_mental_rituals (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_mental_rituals_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_mental_rituals (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_lists_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_lists (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_lists_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_lists (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_lists_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_lists (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_eating_ritual_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_eating_ritual (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_eating_ritual_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_eating_ritual (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_eating_ritual_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_eating_ritual (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_blink_stare_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_blink_stare (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_blink_stare_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_blink_stare (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_misc_blink_stare_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_misc_blink_stare (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_hoarding_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_hoarding_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="com_hoarding_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_hoarding_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_hoarding_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_counting_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_counting_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="com_counting_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_counting_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_counting_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_toileting_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_toileting (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_toileting_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_toileting (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_toileting_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_toileting (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="com_cleaning_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_contaminant_avoidance_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_cleaning_other_contaminant_avoidance (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_contaminant_avoidance_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_cleaning_other_contaminant_avoidance (past symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_other_contaminant_avoidance_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_cleaning_other_contaminant_avoidance (current symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_handwashing_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_handwashing (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_handwashing_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_handwashing (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_handwashing_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_handwashing (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_cleaning_items_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_cleaning_items (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_cleaning_items_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_cleaning_items (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_cleaning_cleaning_items_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_cleaning_cleaning_items (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_somatic_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_somatic (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_somatic_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_somatic (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_somatic_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_somatic (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="com_checking_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_nothing_bad_happens_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_checking_nothing_bad_happens (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_nothing_bad_happens_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_nothing_bad_happens (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_nothing_bad_happens_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_checking_nothing_bad_happens (current symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_self_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_not_harm_self (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_self_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_not_harm_self (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_self_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_not_harm_self (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_others_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_checking_not_harm_others (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_others_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_not_harm_others (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_not_harm_others_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_not_harm_others (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_no_mistake_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_no_mistake (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_no_mistake_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_no_mistake (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_no_mistake_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_no_mistake (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_locks_appliances_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "com_checking_locks_appliances (principal symptom)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_locks_appliances_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_locks_appliances (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_checking_locks_appliances_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_checking_locks_appliances (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_principal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_arranging_other (principal symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_past",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_arranging_other (past symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="com_arranging_other (details)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "com_arranging_other_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="com_arranging_other (current symptom)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ybocs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "target_obsession_3",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: obsession 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_obsession_2",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: obsession 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_obsession_1",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: obsession 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_compulsion_3",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: compulsion 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_compulsion_2",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: compulsion 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_compulsion_1",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: compulsion 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_avoidance_3",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: avoidance 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_avoidance_2",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: avoidance 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_avoidance_1",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Target symptoms: avoidance 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, compulsions: resistance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, compulsions: distress (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, compulsions: interference (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6b, compulsions: compulsion-free interval (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, compulsions: time (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, obsessions: control (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, obsessions: resistance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, obsessions: distress (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, obsessions: interference (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1b, obsessions: obsession-free interval (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q19, reliability (0-3, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q18, global improvement (0-6, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q17, global severity (0-6, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q16, doubting (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q15, slowness (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14, overvalued responsibility (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13, indecisiveness (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12, avoidance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11, insight (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, compulsions: control (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, obsessions: time (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("wsas", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "retired_etc",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Retired or choose not to have job for reason unrelated to"
                " problem"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, relationships (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, private leisure (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, social leisure (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, home management (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, work (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("wemwbs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (feeling close to others) (1 none of the time - 5 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (feeling good about myself) (1 none of the time - 5 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (thinking clearly) (1 none of the time - 5 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (dealing with problems well) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (energy) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (interested in other people) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (relaxed) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (useful) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (cheerful) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (interested in new things) (1 none of the time - 5 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (feeling loved) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (able to make up my own mind) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (confident) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (optimistic) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("swemwbs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (thinking clearly) (1 none of the time - 5 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (dealing with problems well) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (energy) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (interested in other people) (1 none of the time - 5 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (relaxed) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (useful) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (optimistic) (1 none of the time - 5 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("srs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q_session",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Session number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_relationship",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Rating of patient-therapist relationship (0-10, 10 better)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_overall",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Overall rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_goals",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Rating for topics discussed (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_date",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Session date",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_approach",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Rating for therapist's approach (0-10, 10 better)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("smast", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q9: neglected obligations for >=2 days (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q8: trouble at work (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q7: problems with close relative (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q6: ever attended Alcoholics Anonymous (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q5: stop when you want to (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q4: friends/relative think you are a normal drinker (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q3: feel guilty (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q2: near relative worries/complains (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q13: arrested for other drunken behaviour (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q12: arrested for drink-driving (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q11: hospitalized (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q10: sought help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q1: believe you are a normal drinker (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("slums", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "shapespicture_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="BLOB ID of shapes picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9b (clock - time) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9a (clock - hour markers) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8c (reverse 8537) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8b (reverse 648) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7e",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7e (recall car) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7d",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7d (recall house) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7c (recall tie) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7b (recall pen) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7a (recall apple) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6 (animal naming) (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5b (money left) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5a (money spent) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3 (state) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2 (year) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11d",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11d (story - state) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11c (story - back to work) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11b (story - occupation) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11a (story - name) (0 or 2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10b (biggest figure) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10a (X in triangle) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1 (day) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "highschooleducation",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Does that patient have at least a high-school level of"
                " education? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clockpicture_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="BLOB ID of clock picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "alert",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Is the patient alert? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ref_satis_spec", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Rating (0 very poor - 4 excellent)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "good",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="What has been good?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bad",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="What could be improved?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ref_satis_gen", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Rating (0 very poor - 4 excellent)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "good",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="What has been good?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bad",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="What could be improved?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("rand36", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (Walking more than a mile) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (Bending, kneeling, or stooping) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (Climbing one flight of stairs) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (Climbing several flights of stairs) (1 limited a lot - 3"
                " not limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (Lifting or carrying groceries) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (Moderate activities) (1 limited a lot - 3 not limited at"
                " all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q36",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q36 (how true/false: My health is excellent) (1 definitely"
                " true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q35",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q35 (how true/false: I expect my health to get worse) (1"
                " definitely true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q34",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q34 (how true/false: I am as healthy as anybody I know) (1"
                " definitely true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q33",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q33 (how true/false: I seem to get sick a little easier than"
                " other people) (1 definitely true - 5 definitely false)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32 (past 4 weeks, how much of the time has physical"
                " health/emotional problems interfered with social activities"
                " (1 all of the time - 5 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31 (past 4 weeks: Did you feel tired?) (1 all of the time -"
                " 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30 (past 4 weeks: Have you been a happy person?) (1 all of"
                " the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (Vigorous activities) (1 limited a lot - 3 not limited at"
                " all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29 (past 4 weeks: Did you feel worn out?) (1 all of the time"
                " - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28 (past 4 weeks: Have you felt downhearted and blue?) (1"
                " all of the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27 (past 4 weeks: Did you have a lot of energy?) (1 all of"
                " the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26 (past 4 weeks: Have you felt calm and peaceful?) (1 all"
                " of the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25 (past 4 weeks: Have you felt so down in the dumps that"
                " nothing could cheer you up?) (1 all of the time - 6 none of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24 (past 4 weeks: Have you been a very nervous person?) (1"
                " all of the time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23 (past 4 weeks: Did you feel full of pep?) (1 all of the"
                " time - 6 none of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22 (past 4 weeks, pain interfered with normal activity (1"
                " not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (past 4 weeks, how much pain (1 none - 6 very severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (past 4 weeks, to what extent physical health/emotional"
                " problems interfered with social activity) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (health cf. 1y ago) (1 much better - 5 much worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (emotional problems: Didn't do work or other activities"
                " as carefully as usual) (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (emotional problems: Accomplished less than would like)"
                " (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (emotional problems: Cut down work/other activities) (1"
                " yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (physical health: Had difficulty performing the work or"
                " other activities) (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (physical health: Were limited in the kind of work or"
                " other activities) (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (physical health: Accomplished less than would like) (1"
                " yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (physical health: Cut down work/other activities) (1 yes,"
                " 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (Bathing or dressing yourself) (1 limited a lot - 3 not"
                " limited at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (Walking one block) (1 limited a lot - 3 not limited at"
                " all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (Walking several blocks) (1 limited a lot - 3 not limited"
                " at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1 (general health) (1 excellent - 5 poor)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("qolsg", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "utility",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Calculated utility, h",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "gamble_starting_p",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Gamble: starting value of p",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Time gamble was offered (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Time subject responded to gamble (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_responded",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Gamble was responded to? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_p",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Final value of p",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_lottery_option_q",
            existing_type=sa.String(length=7),
            comment=None,
            existing_comment=(
                "Gamble: option corresponding to q  (current, healthy, dead)"
                " (q = 1 - p)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_lottery_option_p",
            existing_type=sa.String(length=7),
            comment=None,
            existing_comment=(
                "Gamble: option corresponding to p  (current, healthy, dead)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_lottery_on_left",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Gamble: lottery shown on the left (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gamble_fixed_option",
            existing_type=sa.String(length=7),
            comment=None,
            existing_comment="Fixed option in gamble (current, healthy, dead)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Time categories were offered (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Time category was chosen (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_responded",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Responded to category choice? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "category_chosen",
            existing_type=sa.String(length=6),
            comment=None,
            existing_comment=(
                "Category chosen: high (QoL > 1) medium (0 <= QoL <= 1) low"
                " (QoL < 0)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("qolbasic", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "tto",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Time trade-off (QoL * 10). Prompt: ... Indicate... the number"
                " of years in full health [0-10] that you think is of equal"
                " value to 10 years in your current health state."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rs",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Rating scale (QoL * 100). Prompt: Mark the point on the scale"
                " [0-100] that you feel best illustrates your current quality"
                " of life."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("pt_satis", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Rating (0 very poor - 4 excellent)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "good",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="What has been good?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bad",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="What could be improved?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("psychiatricclerking", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("pswq", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, finish then worry about next thing (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, easily dismiss worries [REVERSE SCORE] (1-5)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, always worrying (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, worry under pressure (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, cannot help worrying (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, many situations make me worry (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, do not tend to worry [REVERSE SCORE] (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, worries overwhelm (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q16, worry about projects until done (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q15, worry all the time (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14, when start worrying cannot stop (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13, have been worrying (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12, lifelong worrier (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, if nothing more to do, I do not worry [REVERSE SCORE]"
                " (1-5)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, never worry [REVERSE SCORE] (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, OK if not enough time [REVERSE SCORE] (1-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("progressnote", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "note",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinical note",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "location",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Location",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("phq9", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (death/self-harm) (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (psychomotor) (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (concentration) (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (self-esteem/guilt) (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (appetite) (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4 (energy) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3 (sleep) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2 (mood) (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (difficulty in activities) (0 not difficult at all - 3"
                " extremely difficult)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (anhedonia) (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("phq15", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (palpitations) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (fainting) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (dizziness) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (chest pain) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (headaches) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (F - menstrual) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (limb/joint pain) (0 not bothered at all - 2 bothered a"
                " lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (back pain) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (sleep) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (energy) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (nausea/indigestion) (0 not bothered at all - 2 bothered"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (constipation/diarrhoea) (0 not bothered at all - 2"
                " bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (sex) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (breathless) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (stomach pain) (0 not bothered at all - 2 bothered a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("photosequence_photos", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "seqnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Sequence number of this photo (consistently 1-based as of"
                " 2018-12-01)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rotation",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(DEFUNCT COLUMN) Rotation (clockwise, in degrees) to be"
                " applied for viewing"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "photosequence_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Tablet FK to photosequence",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "photo_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "ID of the BLOB (foreign key to blobs.id, given matching"
                " device and current/frozen record status)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Description of the photograph",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("photosequence", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "sequence_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Description of the sequence of photographs",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("photo", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "rotation",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Rotation (clockwise, in degrees) to be applied for viewing"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "photo_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "ID of the BLOB (foreign key to blobs.id, given matching"
                " device and current/frozen record status)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Description of the photograph",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("perinatal_poem", schema=None) as batch_op:
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )

    with op.batch_alter_table("pdss", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, interference with social life (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, interference with responsibilities (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, activities avoided (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, places or situations avoided (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, anxiety about panic (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, distressing during (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, frequency (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("pcls", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (loss of interest in previously enjoyed activities) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (avoid activities/situations because they remind) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (physical reactions to reminders) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (upset at reminders) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3 (reliving) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (disturbing dreams) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (jumpy/easily startled) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (super alert/on guard) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (difficulty concentrating) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14 (irritable) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (hard to sleep) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (feeling future will be cut short) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (feeling emotionally numb) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (feeling distant/cut off from people) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (disturbing memories/thoughts/images) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eventdate",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Date of traumatic event (free text)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "event",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Traumatic event",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("pclm", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (loss of interest in previously enjoyed activities) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (avoid activities/situations because they remind) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (physical reactions to reminders) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (upset at reminders) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3 (reliving) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (disturbing dreams) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (jumpy/easily startled) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (super alert/on guard) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (difficulty concentrating) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14 (irritable) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (hard to sleep) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (feeling future will be cut short) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (feeling emotionally numb) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (feeling distant/cut off from people) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (disturbing memories/thoughts/images) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("pclc", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (loss of interest in previously enjoyed activities) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (avoid activities/situations because they remind) (1 not"
                " at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (physical reactions to reminders) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (upset at reminders) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3 (reliving) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (disturbing dreams) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (jumpy/easily startled) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (super alert/on guard) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (difficulty concentrating) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14 (irritable) (1 not at all - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (hard to sleep) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (feeling future will be cut short) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (feeling emotionally numb) (1 not at all - 5 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (feeling distant/cut off from people) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (disturbing memories/thoughts/images) (1 not at all - 5"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("pcl5", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (strong negative beliefs about self/others/world) (0 not"
                " at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (trouble remembering important parts of stressful event)"
                " (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (avoid activities/situations because they remind) (0 not"
                " at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (avoid thinking/talking/feelings relating to experience)"
                " (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (physical reactions to reminders) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (upset at reminders) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3 (reliving) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (hard to sleep) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (disturbing dreams) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (difficulty concentrating) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (jumpy/easily startled) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (super alert/on guard) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (risk-taking and/or self-harming behaviour) (0 not at all"
                " - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (irritable, angry and/or aggressive) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (feeling emotionally numb) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (feeling distant / cut off from people) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (loss of interest in previously enjoyed activities) (0"
                " not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (strong negative emotions) (0 not at all - 4 extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10 (blaming) (0 not at all - 4 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (disturbing memories/thoughts/images) (0 not at all - 4"
                " extremely)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("pbq", schema=None) as batch_op:
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )

    with op.batch_alter_table("patient_idnum", schema=None) as batch_op:
        batch_op.alter_column(
            "which_idnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Which of the server's ID numbers is this?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to patient.id (for this device/era)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "idnum_value",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="The value of the ID number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Primary key on the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("patient", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "surname",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Surname",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sex",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Sex (M, F, X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Other details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Primary key (patient ID) on the source tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "gp",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="General practitioner (GP)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "forename",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Forename",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dob",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date of birth",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "address",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Address",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("panss", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "p7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="P7: hostility (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "P6: suspiciousness/persecution (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="P5: grandiosity (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="P4: excitement (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "P3: hallucinatory behaviour (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "P2: conceptual disorganisation (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="P1: delusions (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="N7: stereotyped thinking (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "N6: lack of spontaneity/conversation flow (1 absent - 7"
                " extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "N5: difficulty in abstract thinking (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "N4: passive/apathetic social withdrawal (1 absent - 7"
                " extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="N3: poor rapport (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="N2: emotional withdrawal (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="N1: blunted affect (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "g9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "G9: unusual thought content (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G8: uncooperativeness (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G7: motor retardation (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G6: depression (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G5: mannerisms/posturing (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G4: tension (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G3: guilt feelings (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G2: anxiety (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "G16: active social avoidance (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G15: preoccupation (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "G14: poor impulse control (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "G13: disturbance of volition (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "G12: lack of judgement/insight (1 absent - 7 extreme)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G11: poor attention (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G10: disorientation (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="G1: somatic concern (1 absent - 7 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ors", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q_who_other",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Completed by other: who?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_who",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Completed by",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_social",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Social rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_session",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Session number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_overall",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Overall rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_interpersonal",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Interpersonal rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_individual",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Individual rating (0-10, 10 better)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q_date",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Session date",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("npiq", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "severity9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, irritability/lability, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, disinhibition, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, apathy/indifference, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, elation/euphoria, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, anxiety, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, depression/dysphoria, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, agitation/aggression, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, hallucinations, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, appetite/eating, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, night-time behaviour, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, motor disturbance, severity (1-3), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, delusions, severity (1-3), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed9",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q9, irritability/lability, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed8",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q8, disinhibition, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed7",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q7, apathy/indifference, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q6, elation/euphoria, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q5, anxiety, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4, depression/dysphoria, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q3, agitation/aggression, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q2, hallucinations, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed12",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q12, appetite/eating, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed11",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q11, night-time behaviour, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed10",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q10, motor disturbance, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorsed1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q1, delusions, endorsed?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, irritability/lability, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, disinhibition, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, apathy/indifference, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, elation/euphoria, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, anxiety, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, depression/dysphoria, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, agitation/aggression, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, hallucinations, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, appetite/eating, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, night-time behaviour, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, motor disturbance, distress (0-5), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, delusions, distress (0-5), if endorsed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("nart", schema=None) as batch_op:
        batch_op.alter_column(
            "zealot",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced zealot correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "topiary",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced topiary correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thyme",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced thyme correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "syncope",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced syncope correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "superfluous",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced superfluous correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtle",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced subtle correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "simile",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced simile correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sidereal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced sidereal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rarefy",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced rarefy correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "radix",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced radix correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "quadruped",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced quadruped correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "puerperal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced puerperal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "psalm",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced psalm correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "procreate",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced procreate correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "prelate",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced prelate correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "placebo",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced placebo correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "nausea",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced nausea correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "naive",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced naive correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leviathan",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced leviathan correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "labile",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced labile correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "idyll",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced idyll correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hiatus",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced hiatus correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "heir",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced heir correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gouge",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced gouge correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gist",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced gist correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gauche",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced gauche correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gaoled",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced gaoled correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "facade",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced facade correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "equivocal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced equivocal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "drachm",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced drachm correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "detente",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced detente correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depot",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced depot correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "deny",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced deny correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "demesne",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced demesne correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "debt",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced debt correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "courteous",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced courteous correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "chord",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced chord correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cellist",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced cellist correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "catacomb",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced catacomb correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "capon",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced capon correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "campanile",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced campanile correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bouquet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced bouquet correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "beatify",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced beatify correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "banal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced banal correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aver",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced aver correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "assignate",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced assignate correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aisle",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced aisle correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aeon",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced aeon correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ache",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced ache correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "abstemious",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Pronounced abstemious correctly (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("moca", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "trailpicture_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="BLOB ID of trail picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 2 (not scored), 5: RED (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 2 (not scored), 4: DAISY (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 2 (not scored), 3: CHURCH (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 2 (not scored), 2: VELVET (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial2_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 2 (not scored), 1: FACE (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 1 (not scored), 5: RED (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 1 (not scored), 4: DAISY (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 1 (not scored), 3: CHURCH (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 1 (not scored), 2: VELVET (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "register_trial1_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Registration, trial 1 (not scored), 1: FACE (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with multiple-choice cue (not scored), 5: RED (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with multiple-choice cue (not scored), 4: DAISY (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with multiple-choice cue (not scored), 3: CHURCH (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with multiple-choice cue (not scored), 2: VELVET (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_mc_cue_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with multiple-choice cue (not scored), 1: FACE (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with category cue (not scored), 5: RED (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with category cue (not scored), 4: DAISY (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with category cue (not scored), 3: CHURCH (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with category cue (not scored), 2: VELVET (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recall_category_cue_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Recall with category cue (not scored), 1: FACE (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9 (attention/5 digits) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8 (naming/camel) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7 (naming/rhino) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6 (naming/lion) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5 (VSE/clock/hands) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4 (VSE/clock/numbers) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3 (VSE/clock/contour) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q28 (orientation/city) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q27 (orientation/place) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q26 (orientation/day) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q25 (orientation/year) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q24 (orientation/month) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q23 (orientation/date) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q22 (recall word/red) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q21 (recall word/daisy) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q20 (recall word/church) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2 (VSE/cube) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q19 (recall word/velvet) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q18 (recall word/face) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q17 (abstraction 2) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q16 (abstraction 1) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q15 (language/fluency) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14 (language/sentence 2) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13 (language/sentence 1) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12 (attention/serial 7s) (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11 (attention/tapping) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10 (attention/3 digits) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1 (VSE/path) (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "education12y_or_less",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="<=12 years of education (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cubepicture_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="BLOB ID of cube picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clockpicture_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="BLOB ID of clock picture",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("mds_updrs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q4_6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part IV, Q4.6  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part IV, Q4.5  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part IV, Q4.4  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part IV, Q4.3  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part IV, Q4.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part IV, Q4.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3c1",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Part III, Q3c.1 (minutes since last dose)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3c",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Part III, Q3c (levodopa)  (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3b",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Part III, Q3b (clinical state)  (0 off, 1 on)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3a",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Part III, Q3a (medication)  (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_hy_stage",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Part III, q3_hy_stage (0-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_dyskinesia_present",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Part III, q3_dyskinesia_present  (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_dyskinesia_interfered",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Part III, q3_dyskinesia_interfered  (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.9  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_8b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.8b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_8a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.8a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_7b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.7b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_7a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.7a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_6b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.6b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_6a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.6a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_5b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.5b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_5a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.5a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_4b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.4b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_4a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.4a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3e",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.3e  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3d",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.3d  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.3c  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.3b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_3a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.3a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.18  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17e",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.17e  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17d",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.17d  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.17c  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.17b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_17a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.17a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_16b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.16b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_16a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.16a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_15b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.15b  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_15a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.15a  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.14  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.13  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.12  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.11  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.10  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part III, Q3.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.9  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.8  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.7  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.6  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.5  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.4  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.3  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.13  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.12  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.11  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.10  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part II, Q2.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I: informant for Q1.1-1.6 (0 patient, 1 caregiver, 2"
                " both)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.9  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.8  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.7  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_6a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.6a: informant for Q1.7-1.13 (0 patient, 1"
                " caregiver, 2 both)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.6  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.5  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.4  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.3  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.2  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.13  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.12  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.11  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.10  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Part I, Q1.1  (0 normal, 1 slight, 2 mild, 3 moderate, 4"
                " severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("mast", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q9: physical fights (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q8: attended Alcoholics Anonymous (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q7: can stop drinking when you want (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q6: friends/relatives think you are a normal drinker (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q5: feel guilty (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q4: stop drinking after 1-2 drinks (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q3: relative worries/complains (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q24: arrested for other drunk behaviour (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q23: arrested for drink-driving (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q22: clinic visit or professional help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q21: psychiatry admission (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q20: hospitalized (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q2: couldn't remember evening before (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q19: sought help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q18: delirium tremens (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q17: liver trouble (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q16: drink before noon often (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q15: neglected obligations for >=2 days (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q14: lost job (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q13: trouble at work/school (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q12: lost friends (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q11: family have sought help (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q10: drinking caused problems with relatives (Y or N)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q1: feel you are a normal drinker (Y or N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "khandaker_1_medicalhistory", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "visual_impairment_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respiratory_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "renal_urinary_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other_inflammatory_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other_endocrinological_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "musculoskeletal_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ms_pd_dementia_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infections_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "heart_disorder_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "haematological_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gastrointestinal_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "epilepsy_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "diabetes_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "dermatological_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cva_headinjury_braintumour_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cerebralpalsy_otherbrain_yn",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cancer_yn", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("irac", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aim",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Main aim of the contact",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "achieved",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Was the aim achieved? (0 not, 1 partially, 2 fully)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ifs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q8_sentence3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8. Hayling, sentence 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8_sentence2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8. Hayling, sentence 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8_sentence1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8. Hayling, sentence 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7_proverb3",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Q7. Proverb 3 (1 = correct explanation, 0.5 = example, 0 ="
                " neither)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7_proverb2",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Q7. Proverb 2 (1 = correct explanation, 0.5 = example, 0 ="
                " neither)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7_proverb1",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Q7. Proverb 1 (1 = correct explanation, 0.5 = example, 0 ="
                " neither)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6. Spatial working memory, sequence 4",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6. Spatial working memory, sequence 3",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6. Spatial working memory, sequence 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6_seq1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6. Spatial working memory, sequence 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5. Verbal working memory",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len7_2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 7, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len7_1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 7, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len6_2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 6, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len6_1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 6, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len5_2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 5, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len5_1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 5, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len4_2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 4, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len4_1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 4, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len3_2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 3, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len3_1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 3, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len2_2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 2, trial 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4_len2_1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Q4. Digits backward, length 2, trial 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3. Go/no-go (inhibitory control)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2. Conflicting instructions (interference sensitivity)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1. Motor series (motor programming)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("iesr", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, mental pictures (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, avoided reminder (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, unreal (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, thought unwanted (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, avoided getting upset (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, irritable (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, reminder thinking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q22, avoided talking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q21, vigilant (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q20, dreams (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, sleep maintenance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q19, reminder physical (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q18, concentration (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q17, tried forgetting (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q16, waves of emotion (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q15, sleep initiation (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14, as if then (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13, numb (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12, feelings undealt (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11, avoided thinking (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, jumpy (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, reminder feelings (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "event",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Relevant event",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ided3d_trials", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "Trial start time / stimuli presented at (ISO-8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Trial number (1-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "stage",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Stage number (1-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Time of response (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_latency_ms",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Response latency (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "responded",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Did the subject respond?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_shape",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Shape# of incorrect stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of copies of incorrect stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_location",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Location of incorrect stimulus (0 top, 1 right, 2 bottom, 3"
                " left)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_colour",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="HTML colour of incorrect stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Response was incorrect",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ided3d_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to ided3d",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "correct_shape",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Shape# of correct stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of copies of correct stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_location",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Location of correct stimulus (0 top, 1 right, 2 bottom, 3"
                " left)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_colour",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="HTML colour of correct stimulus",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Response was correct",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ided3d_stages", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage_passed",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Subject met criterion and passed stage",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Name of the stage (e.g. SD, EDr)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage_failed",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Subject took too many trials and failed stage",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stage",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Stage number (1-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "relevant_dimension",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Relevant dimension (e.g. shape, colour, number)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_incorrect",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of trials performed incorrectly",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_correct",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of trials performed correctly",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_completed_trials",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of trials completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_stimulus_shapes",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Possible shapes for incorrect stimulus (CSV list of shape"
                " numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_stimulus_numbers",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Possible numbers for incorrect stimulus (CSV list of numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_stimulus_colours",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Possible colours for incorrect stimulus (CSV list of HTML"
                " colours)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "incorrect_exemplar",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Incorrect exemplar (from relevant dimension)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ided3d_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to ided3d",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "first_trial_num",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Number of the first trial of the stage (1-based)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_stimulus_shapes",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Possible shapes for correct stimulus (CSV list of shape"
                " numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_stimulus_numbers",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Possible numbers for correct stimulus (CSV list of numbers)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_stimulus_colours",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Possible colours for correct stimulus (CSV list of HTML"
                " colours)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct_exemplar",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Correct exemplar (from relevant dimension)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ided3d", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "volume",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Sound volume (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "shape_definitions_svg",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "JSON-encoded version of shape definition array in SVG format"
                " (with arbitrary scale of -60 to +60 in both X and Y"
                " dimensions)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "progress_criterion_y",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Criterion to proceed to next stage: X correct out of the last"
                " Y trials, where this is Y"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "progress_criterion_x",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Criterion to proceed to next stage: X correct out of the last"
                " Y trials, where this is X"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_after_beep_ms",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Time to continue visual feedback after auditory feedback"
                " finished (ms)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "offer_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Offer an abort button?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "min_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Minimum number of stimulus element to use",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "max_trials_per_stage",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Maximum number of trials allowed per stage before the task"
                " aborts"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "max_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Maximum number of stimulus element to use",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_trial_completed",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of last trial completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_stage",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Last stage to offer (1 [SD] - 8 [EDR])",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_ms",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Intertrial interval (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finished",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Was the task finished? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "debug_display_stimuli_only",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="DEBUG: show stimuli only, don't run task",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "counterbalance_dimensions",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Dimensional counterbalancing condition (0-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "colour_definitions_rgb",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="JSON-encoded version of colour RGB definitions",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aborted",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Was the task aborted? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10specpd", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "vignette",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Vignette",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_schizoid",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for schizoid PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_paranoid",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for paranoid PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_histrionic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for histrionic PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_eu",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for emotionally unstable PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_dissocial",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for dissocial PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_dependent",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for dependent PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_anxious",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for anxious PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "skip_anankastic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Skip questions for anankastic PD?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid9",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (9): insensitive to social norms",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid8",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (8): 0/1 close friends/confidants",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid7",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (7): fantasy/introspection",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (6): solitary",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (5): little interest in sex",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (4): indifferent to praise/criticism",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (3): limited capacity for warmth",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (2): cold/detached",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "schizoid1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Schizoid (1): little pleasure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "paranoid7",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Paranoid (7): conspiratorial",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Paranoid (6): self-referential",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Paranoid (5): sexual jealousy",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Paranoid (4): personal rights",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Paranoid (3): suspicious",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Paranoid (2): grudges",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "paranoid1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Paranoid (1): sensitive",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other_pd_present",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Is another personality disorder present?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "histrionic6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Histrionic (6): concerned with attractiveness",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Histrionic (5): inappropriately seductive",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Histrionic (4): centre of attention",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Histrionic (3): shallow/labile affect",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Histrionic (2): suggestibility",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "histrionic1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Histrionic (1): theatricality",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G6: primary 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G5: primary 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G4: persistent",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G3: pathological 2",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G2: pervasive",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G14: interpersonal",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G13: impulse control",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G12: affectivity",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1_1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G11: cognition",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "g1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="G1: pathological 1",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu9",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Emotionally unstable (9): threats/acts of self-harm"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu8",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Emotionally unstable (8): avoids abandonment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu7",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Emotionally unstable (7): intense/unstable relationships"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Emotionally unstable (6): uncertain self-image",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Emotionally unstable (5): unstable/capricious mood"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Emotionally unstable (4): can't maintain actions with"
                " immediate reward"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Emotionally unstable (3): outbursts of anger",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Emotionally unstable (2): quarrelsome",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu10",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Emotionally unstable (10): feelings of emptiness"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eu1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Emotionally unstable (1): act without considering"
                " consequences"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Dissocial (6): prone to blame others",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Dissocial (5): incapacity for guilt",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Dissocial (4): low tolerance to frustration",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Dissocial (3): incapacity to maintain relationships"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Dissocial (2): irresponsibility",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dissocial1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Dissocial (1): unconcern",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Dependent (6): everyday decisions require advice/reassurance"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Dependent (5): fears of being left to oneself",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Dependent (4): uncomfortable/helpless when alone"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Dependent (3): unwilling to make reasonable demands"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Dependent (2): subordinate needs to those of others"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dependent1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Dependent (1): others decide",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anxious (5), avoidance of interpersonal contact",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Anxious (4), need for security restricts lifestyle"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Anxious (3), won't get involved unless certain liked"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Anxious (2), preoccupied with criticism/rejection"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anxious1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anxious (1), tension/apprehension",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic8",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Anankastic (8): require others do things specific way"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic7",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anankastic (7): rigid/stubborn",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anankastic (6): excessive pedantry",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anankastic (5): preoccupied with productivity",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anankastic (4): excessively conscientious",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anankastic (3): perfectionism",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anankastic (2): preoccupation with details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anankastic1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Anankastic (1): doubt/caution",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10schizotypal", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "b",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Criterion (B). True if: the subject has never met the"
                " criteria for any disorder in F20 (Schizophrenia)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a9",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Criterion A(9), occasional transient quasi-psychotic episodes"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a8",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Criterion A(8),"
                " vague/circumstantial/metaphorical/over-elaborate/stereotyped"
                " thinking"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a7",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Criterion A(7), unusual perceptual experiences",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a6",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Criterion A(6), ruminations without inner resistance"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a5",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Criterion A(5), suspiciousness/paranoid ideas",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a4",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Criterion A(4), odd beliefs/magical thinking",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a3",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Criterion A(3), poor rapport/social withdrawal",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a2",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Criterion A(2), odd/eccentric/peculiar",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "a1",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Criterion A(1), inappropriate/constricted affect"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10schizophrenia", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "thought_withdrawal",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Thought withdrawal [the feeling that one's thoughts have been"
                " removed by an outside agency]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_insertion",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Thought insertion [the feeling that one's thoughts have been"
                " placed there from outside]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_echo",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Thought echo [hearing one's own thoughts aloud, just before,"
                " just after, or simultaneously with the thought]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_disorder",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Thought disorder: breaks or interpolations in the train of"
                " thought, resulting in incoherence or irrelevant speech, or"
                " neologisms."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "thought_broadcasting",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Thought broadcasting [the feeling that one's thoughts leave"
                " oneself and are diffused widely, or are audible to others,"
                " or that others think the same thoughts in unison]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_undifferentiated",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "UNDIFFERENTIATED (F20.3): schizophrenia with active psychosis"
                " fitting none or more than one of the above three types."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_simple",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "SIMPLE SCHIZOPHRENIA (F20.6), in which 'negative' symptoms"
                " (C) with a change in personal behaviour (D) develop for at"
                " least one year without any psychotic episodes (no symptoms"
                " from groups A or B or other hallucinations or well-formed"
                " delusions), and with a marked decline in social, scholastic,"
                " or occupational performance."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_residual",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "RESIDUAL (F20.5): in which previous psychotic episodes of"
                " schizophrenia have given way to a chronic condition with"
                " 'negative' symptoms of schizophrenia for at least 1 year."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_postschizophrenic_depression",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "POST-SCHIZOPHRENIC DEPRESSION (F20.4): in which a depressive"
                " episode has developed for at least 2 weeks following a"
                " schizophrenic episode within the last 12 months and in which"
                " schizophrenic symptoms persist but are not as prominent as"
                " the depression."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_paranoid",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "PARANOID (F20.0): dominated by delusions or hallucinations."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_hebephrenic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "HEBEPHRENIC (F20.1): dominated by affective changes (shallow,"
                " flat, incongruous, or inappropriate affect) and either"
                " pronounced thought disorder or aimless, disjointed behaviour"
                " is present."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_cenesthopathic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "CENESTHOPATHIC (within OTHER F20.8): body image aberration"
                " (e.g. desomatization, loss of bodily boundaries, feelings of"
                " body size change) or abnormal bodily sensations (e.g."
                " numbness, stiffness, feeling strange, depersonalization, or"
                " sensations of pain, temperature, electricity, heaviness,"
                " lightness, or discomfort when touched) dominate."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subtype_catatonic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "CATATONIC (F20.2): psychomotor disturbances dominate (such as"
                " stupor, mutism, excitement, posturing, negativism, rigidity,"
                " waxy flexibility, command automatisms, or verbal"
                " perseveration)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "present_one_month",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Symptoms in groups A-C present for most of the time during an"
                " episode of psychotic illness lasting for at least one month"
                " (or at some time during most of the days)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "performance_decline",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Marked decline in social, scholastic, or occupational"
                " performance."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "passivity_mental",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(passivity) ... or to specific thoughts, actions, or"
                " sensations."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "passivity_bodily",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Passivity: delusions of control, influence, or passivity,"
                " clearly referred to body or limb movements..."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "not_organic_or_substance",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "The disorder is not attributable to organic brain disease (in"
                " the sense of F0), or to alcohol- or drug-related"
                " intoxication, dependence or withdrawal."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "negative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Negative symptoms: 'negative' symptoms such as marked apathy,"
                " paucity of speech, and blunting or incongruity of emotional"
                " responses, usually resulting in social withdrawal and"
                " lowering of social performance; it must be clear that these"
                " are not due to depression or to neuroleptic medication."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "if_mood_psychosis_first",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "If the patient also meets criteria for manic episode (F30) or"
                " depressive episode (F32), the criteria listed above must"
                " have been met before the disturbance of mood developed."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hv_from_body",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Other types of hallucinatory voices coming from some part of"
                " the body"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hv_discussing",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Hallucinatory voices discussing the patient among themselves"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hv_commentary",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Hallucinatory voices giving a running commentary on the"
                " patient's behaviour"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Hallucinations: persistent hallucinations in any modality,"
                " when accompanied either by fleeting or half-formed delusions"
                " without clear affective content, or by persistent"
                " over-valued ideas, or when occurring every day for weeks or"
                " months on end."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Delusions: persistent delusions of other kinds that are"
                " culturally inappropriate and completely impossible, such as"
                " religious or political identity, or superhuman powers and"
                " abilities (e.g. being able to control the weather, or being"
                " in communication with aliens from another world)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusional_perception",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Delusional perception [a normal perception, delusionally"
                " interpreted]"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "catatonia",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Catatonia: catatonic behaviour, such as excitement,"
                " posturing, or waxy flexibility, negativism, mutism, and"
                " stupor."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "behaviour_change",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "A significant and consistent change in the overall quality of"
                " some aspects of personal behaviour, manifest as loss of"
                " interest, aimlessness, idleness, a self-absorbed attitude,"
                " and social withdrawal."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "also_manic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Also meets criteria for manic episode (F30)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "also_depressive",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Also meets criteria for depressive episode (F32)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10mixed", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mixture_or_rapid_alternation",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "The episode is characterized by either a mixture or a rapid"
                " alternation (i.e. within a few hours) of hypomanic, manic"
                " and depressive symptoms."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "duration_at_least_2_weeks",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Both manic and depressive symptoms must be prominent most of"
                " the time during a period of at least two weeks."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10manic", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "talkativeness",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Increased talkativeness (pressure of speech).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sustained7days",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Elevated/irritable mood sustained for at least 7 days."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sustained4days",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Elevated/irritable mood sustained for at least 4 days."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "some_interference_functioning",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Some interference with personal functioning in daily living."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "social_disinhibition",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Increased sociability or over-familiarity [hypomania]; loss"
                " of normal social inhibitions resulting in behaviour which is"
                " inappropriate to the circumstances [mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Decreased need for sleep.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sexual",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Increased sexual energy [hypomania]; marked sexual energy or"
                " sexual indiscretions [mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severe_interference_functioning",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Severe interference with personal functioning in daily"
                " living."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recklessness",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Mild spending sprees, or other types of reckless or"
                " irresponsible behaviour [hypomania]; behaviour which is"
                " foolhardy or reckless and whose risks the subject does not"
                " recognize e.g. spending sprees, foolish enterprises,"
                " reckless driving [mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "perceptual_alterations",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Perceptual alterations (e.g. subjective hyperacusis,"
                " appreciation of colours as specially vivid, etc.)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mood_irritable",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "The mood is 'irritable' [hypomania] or 'predominantly"
                " irritable' [mania] to a degree that is definitely abnormal"
                " for the individual concerned."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mood_elevated",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "The mood is 'elevated' [hypomania] or 'predominantly elevated"
                " [or] expansive' [mania] to a degree that is definitely"
                " abnormal for the individual concerned."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hallucinations_schizophrenic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Hallucinations that are 'typically schizophrenic'"
                " (hallucinatory voices giving a running commentary on the"
                " patient's behaviour, or discussing him between themselves,"
                " or other types of hallucinatory voices coming from some part"
                " of the body)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Hallucinations (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "grandiosity",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Inflated self-esteem or grandiosity.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "flight_of_ideas",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Flight of ideas or the subjective experience of thoughts"
                " racing."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distractible",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Difficulty in concentration or distractibility [from the"
                " criteria for hypomania]; distractibility or constant changes"
                " in activity or plans [from the criteria for mania]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_schizophrenic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Delusions that are 'typically schizophrenic' (delusions of"
                " control, influence or passivity, clearly referred to body or"
                " limb movements or specific thoughts, actions, or sensations;"
                " delusional perception; persistent delusions of other kinds"
                " that are culturally inappropriate and completely"
                " impossible)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Delusions (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_required",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Elevated/irritable mood severe enough to require hospital"
                " admission."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "activity",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Increased activity or physical restlessness.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("icd10depressive", schema=None) as batch_op:
        batch_op.alter_column(
            "worth",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Loss of confidence and self-esteem.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "stupor",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Depressive stupor.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_weight",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Weight loss (5 percent or more of body weight in the past"
                " month)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_psychomotor",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Objective evidence of marked psychomotor retardation or"
                " agitation (remarked on or reported by other people)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_mood_worse_morning",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Depression worse in the morning",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_libido",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Marked loss of libido",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_emotional_unreactivity",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Lack of emotional reactions to events or activities that"
                " normally produce an emotional response"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_early_morning_waking",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Waking in the morning 2 hours or more before the usual time"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_appetite",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Marked loss of appetite",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_anhedonia",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Marked loss of interest or pleasure in activities that are"
                " normally pleasurable"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Sleep disturbance of any type.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severe_clinically",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Clinical impression of severe depression, in a patient"
                " unwilling or unable to describe many symptoms in detail"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mood",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Depressed mood to a degree that is definitely abnormal for"
                " the individual, present for most of the day and  almost"
                " every day, largely uninfluenced by circumstances, and"
                " sustained for at least 2 weeks."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hallucinations_schizophrenic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Hallucinations that are 'typically schizophrenic'"
                " (hallucinatory voices giving a running commentary on the"
                " patient's behaviour, or discussing him between themselves,"
                " or other types of hallucinatory voices coming from some part"
                " of the body)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hallucinations_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Hallucinations (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "guilt",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Unreasonable feelings of self-reproach or excessive and"
                " inappropriate guilt."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "energy",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Decreased energy or increased fatiguability.",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "duration_at_least_2_weeks",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Depressive episode lasts at least 2 weeks?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_schizophrenic",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Delusions that are 'typically schizophrenic' (delusions of"
                " control, influence or passivity, clearly referred to body or"
                " limb movements or specific thoughts, actions, or sensations;"
                " delusional perception; persistent delusions of other kinds"
                " that are culturally inappropriate and completely"
                " impossible)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "delusions_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Delusions (of any other kind).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "death",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Recurrent thoughts of death or suicide, or any suicidal"
                " behaviour."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date_pertains_to",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date the assessment pertains to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "concentration",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Complaints or evidence of diminished ability to think or"
                " concentrate, such as indecisiveness or vacillation."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "appetite",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Change in appetite (decrease or increase) with corresponding"
                " weight change."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anhedonia",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Loss of interest or pleasure in activities  that are normally"
                " pleasurable."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "activity",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Change in psychomotor activity, with agitation or retardation"
                " (either subjective or objective)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("honosca", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, emotional symptoms (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, non-organic somatic symptoms (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, delusions/hallucinations (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, physical illness/disability (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, scholastic/language problems (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, alcohol/drug misuse (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, self-harm (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, overactive/inattentive (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15, lack of information about services (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14, problems with knowledge/understanding of child's"
                " problems (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13, school attendance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, family life/relationships (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, self-care and independence (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, peer relationships (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, disruptive/antisocial/aggressive (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "period_rated",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Period being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("honos65", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, relationship problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8problemtype",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q8: type of problem (A phobic; B anxiety; C"
                " obsessive-compulsive; D stress; E dissociative; F"
                " somatoform; G eating; H sleep; I sexual; J other, specify)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8otherproblem",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Q8: other problem: specify",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, other mental/behavioural problem (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, depressive symptoms (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, hallucinations/delusions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, physical illness/disability (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, cognitive problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, problem drinking/drug-taking (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, deliberate self-harm (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12, occupation/activities (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11, living conditions (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, activities of daily living (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, behavioural disturbance (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "period_rated",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Period being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("honos", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, relationship problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8problemtype",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q8: type of problem (A phobic; B anxiety; C"
                " obsessive-compulsive; D mental strain/tension; E"
                " dissociative; F somatoform; G eating; H sleep; I sexual; J"
                " other, specify)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8otherproblem",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Q8: other problem: specify",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, other mental/behavioural problem (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, depressed mood (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, hallucinations/delusions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, physical illness/disability (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, cognitive problems (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, problem-drinking/drug-taking (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, deliberate self-harm (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12, occupation/activities (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, problems with living conditions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, activities of daily living (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, overactive/aggressive/disruptive/agitated (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "period_rated",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Period being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("hamd7", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, suicide (0-4, except Q6 0-2; higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, energy/somatic symptoms (0-4, except Q6 0-2; higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, somatic anxiety (0-4, except Q6 0-2; higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, psychological anxiety (0-4, except Q6 0-2; higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, interest/pleasure/level of activities (0-4, except Q6"
                " 0-2; higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, guilt (0-4, except Q6 0-2; higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, depressed mood (0-4, except Q6 0-2; higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("hamd", schema=None) as batch_op:
        batch_op.alter_column(
            "whichq16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Method of assessing weight loss (0 = A, by history; 1 = B, by"
                " measured change)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, agitation (scored 0-4, except 0-2 for Q4-6/12-14, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, psychomotor retardation (scored 0-4, except 0-2 for"
                " Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, work/activities (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, late insomnia (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, middle insomnia (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, early insomnia (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, suicide (scored 0-4, except 0-2 for Q4-6/12-14, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (not scored), obsessional/compulsive symptoms (0-4 for"
                " Q19, 0-3 for Q20, 0-2 for Q21, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (not scored), paranoid symptoms (0-4 for Q19, 0-3 for"
                " Q20, 0-2 for Q21, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, guilt (scored 0-4, except 0-2 for Q4-6/12-14, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (not scored), depersonalization/derealization (0-4 for"
                " Q19, 0-3 for Q20, 0-2 for Q21, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18B (not scored), diurnal variation, severity (0-2, higher"
                " more severe)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18A (not scored), diurnal variation, presence (0 none, 1"
                " worse AM, 2 worse PM)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q17, lack of insight (0-2, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16B, weight loss, by measurement (0 none - 2 more than 2lb,"
                " or 3 not assessed [not scored])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16A, weight loss, by history (0 none - 2 definite, or 3 not"
                " assessed [not scored])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15, hypochondriasis (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14, genital symptoms (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13, somatic symptoms, general (scored 0-4, except 0-2 for"
                " Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, somatic symptoms, gastointestinal (scored 0-4, except"
                " 0-2 for Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, anxiety, somatic (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, anxiety, psychological (scored 0-4, except 0-2 for"
                " Q4-6/12-14, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, depressed mood (scored 0-4, except 0-2 for Q4-6/12-14,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("hama", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, cardiovascular (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, somatic, sensory (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, somatic, muscular (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, depressed mood (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, concentration/memory (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, insomnia (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, fears (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, tension (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14, behaviour in interview (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13, other autonomic (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12, genitourinary (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11, gastrointestinal (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, respiratory (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, anxious mood (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("hads_respondent", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9: butterflies (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8: slow (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7: relaxed (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6: cheerful (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5: worry (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4: laugh (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3: apprehensive (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2: enjoy usual (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14: book/TV/radio (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13: panic (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12: anticipate (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11: restless (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10: appearance (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1: tense (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("hads", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9: butterflies (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8: slow (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7: relaxed (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6: cheerful (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5: worry (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4: laugh (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3: apprehensive (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2: enjoy usual (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q14: book/TV/radio (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q13: panic (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12: anticipate (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q11: restless (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10: appearance (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1: tense (0-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("gmcpq", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Other comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Was this visit with your usual doctor (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Would be completely happy to see this doctor again (0 no, 1"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Confident in doctor's ability to provide care (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Agree/disagree: honest/trustworthy (1 strongly disagree - 5"
                " strongly agree, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Agree/disagree: will keep info confidential (1 strongly"
                " disagree - 5 strongly agree, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4g",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How good: providing/arranging treatment (1 poor - 5 very"
                " good, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4f",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How good: involving you in decisions (1 poor - 5 very good, 0"
                " does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4e",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How good: explaining (1 poor - 5 very good, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4d",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How good: assessing medical condition (1 poor - 5 very good,"
                " 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How good: listening (1 poor - 5 very good, 0 does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How good: making you feel at ease (1 poor - 5 very good, 0"
                " does not apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How good: being polite (1 poor - 5 very good, 0 does not"
                " apply)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How important to health/wellbeing was the reason (1 not very"
                " - 5 very)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2f_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Reason, other, details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2f",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Reason: other? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2e",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Reason: treatment? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2d",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Reason: routine check? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Reason: ongoing problem? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Reason: one-off problem? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Reason: advice? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Ethnic group, other, details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Ethnicity (1 = White British, 2 = White Irish, 3 = White"
                " other, 4 = Mixed W/B Caribbean, 5 = Mixed W/B African, 6 ="
                " Mixed W/Asian, 7 = Mixed other, 8 = Asian/Asian British -"
                " Indian, 9 = A/AB - Pakistani, 10 = A/AB - Bangladeshi, 11 ="
                " A/AB - other, 12 = Black/Black British - Caribbean, 13 ="
                " B/BB - African, 14 = B/BB - other, 15 = Chinese, 16 = other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Age (1 = under 15, 2 = 15-20, 3 = 21-40, 4 = 40-60, 5 = 60 or"
                " over"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Sex of rater (M, F)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Filling in questionnaire for... (1 yourself, 2 child, 3"
                " spouse/partner, 4 other relative/friend)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "doctor",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Doctor's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("gds15", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q9, stay at home ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q8, helpless ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q7, happy ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q6, afraid ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q5, good spirits ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q4, bored ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q3, life empty ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q2, dropped activities ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q15, others better off ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q14, hopeless ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q13, full of energy ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q12, worthless ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q11, wonderful to be alive ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q10, memory problems ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q1, satisfied ('Y' or 'N')",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("gbogres", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other_goals",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Other/additional goal description(s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "goal_3_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Goal 3 description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_2_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Goal 2 description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_1_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Goal 1 description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date of goal-setting",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by_other",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="If completed by 'other', who?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Who completed the form (1 = Patient/service user; 2 ="
                " Parent/carer; 3 = Practitioner/clinician; 4 = Other: )"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("gbogras", schema=None) as batch_op:
        batch_op.alter_column(
            "rate_goal_3",
            existing_type=sa.Boolean(),
            existing_comment="Rate goal 3?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rate_goal_2",
            existing_type=sa.Boolean(),
            existing_comment="Rate goal 2?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rate_goal_1",
            existing_type=sa.Boolean(),
            existing_comment="Rate goal 1?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )

    with op.batch_alter_table("gbogpc", schema=None) as batch_op:
        batch_op.alter_column(
            "whose_goal_other",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="If 'whose goal' is 'other', who?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "whose_goal",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Whose goal is this (1 = Patient/service user; 2 ="
                " Parent/carer; 3 = Practitioner/clinician; 4 = Other: )"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "session",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Session number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "progress",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Progress towards goal (0 no progress - 10 reached fully)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "goal_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Goal number (1-3)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "goal_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Brief description of the goal",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Session date",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("gaf", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "score",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "GAF score (1-100 or 0 for insufficient information)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("gad7", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, afraid (0 not at all - 3 nearly every day)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, irritable (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, restless (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, trouble relaxing (0 not at all - 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, worrying too much about different things (0 not at all -"
                " 3 nearly every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, can't stop/control worrying (0 not at all - 3 nearly"
                " every day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, nervous/anxious/on edge (0 not at all - 3 nearly every"
                " day)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("frs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, outings / shopping (0 = never, 2 = always, 1 = sometimes,"
                " -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, outings / transportation (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, behaviour / forgets day (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, behaviour / impulsive (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, behaviour / restless (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, behaviour / confused/muddled in unusual surroundings (0 ="
                " never, 2 = always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30, selfcare / bedbound (0 = never, 2 = always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, behaviour / uncooperative (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29, selfcare / cannot be left at home safely (0 = never, 2 ="
                " always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28, selfcare / incontinent (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27, selfcare / problems choosing appropriate clothing (0 ="
                " never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26, mealprep / prefers sweet foods more (0 = never, 2 ="
                " always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25, mealprep / wants to eat same foods repeatedly (0 ="
                " never, 2 = always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24, mealprep / problems eating (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23, mealprep / difficulty choosing utensils/seasoning (0 ="
                " never, 2 = always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22, mealprep / lacks initiative to eat (0 = never, 2 ="
                " always, 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21, mealprep / problems preparing meal on own (0 = never, 2"
                " = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20, mealprep / difficulty organizing meal prep (0 = never, 2"
                " = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, behaviour / lacks affection (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19, mealprep / lacks interest/motivation (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18, medication / problems taking medication as prescribed (0"
                " = never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17, medication / problems taking medication at correct time"
                " (0 = never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16, finances / difficulty with cash (0 = never, 2 = always,"
                " 1 = sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15, finances / problems organizing correspondence (0 ="
                " never, 2 = always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14, finances / problems organizing finances (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13, finances / lacks interest (0 = never, 2 = always, 1 ="
                " sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, household / telephoning (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, household / difficulty completing chores (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, household / lacks interest/motivation (0 = never, 2 ="
                " always, 1 = sometimes, -99 = N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, behaviour / lacks interest (0 = never, 2 = always, 1 ="
                " sometimes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("fft", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinical service being rated",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Likelihood of recommendation to friends/family (1 extremely"
                " likely - 5 extremely unlikely, 6 don't know)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("fast", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4. others concerned (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3. failed to do what was expected (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2. unable to remember (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1. M>8, F>6 drinks (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("factg", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "s_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Social well-being Q7 (satisfied with sex life) (0 not at all,"
                " 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Social well-being Q6 (feel close to partner/main supporter)"
                " (0 not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Social well-being Q5 (good family comms re illness) (0 not at"
                " all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Social well-being Q4 (family accepted illness) (0 not at all,"
                " 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Social well-being Q3 (support from friends) (0 not at all, 1"
                " a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Social well-being Q2 (emotional support from family) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Social well-being Q1 (close to friends) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "p_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical well-being Q7 (bedbound) (0 not at all, 1 a little"
                " bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical well-being Q6 (feel ill) (0 not at all, 1 a little"
                " bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical well-being Q5 (treatment side effects) (0 not at"
                " all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical well-being Q4 (pain) (0 not at all, 1 a little bit,"
                " 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical well-being Q3 (trouble meeting family needs) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical well-being Q2 (nausea) (0 not at all, 1 a little"
                " bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "p_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical well-being Q1 (lack of energy) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ignore_s_q7", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Functional well-being Q7 (content with quality of life) (0"
                " not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Functional well-being Q6 (enjoying usual fun things) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Functional well-being Q5 (sleeping well) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Functional well-being Q4 (accepted illness) (0 not at all, 1"
                " a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Functional well-being Q3 (able to enjoy life) (0 not at all,"
                " 1 a little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Functional well-being Q2 (work fulfilling) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "f_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Functional well-being Q1 (able to work) (0 not at all, 1 a"
                " little bit, 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Emotional well-being Q6 () (0 not at all, 1 a little bit, 2"
                " somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Emotional well-being Q5 (worried condition will worsen) (0"
                " not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Emotional well-being Q4 (nervousworried about dying) (0 not"
                " at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4 very"
                " much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Emotional well-being Q3 (losing hope in fight against"
                " illness) (0 not at all, 1 a little bit, 2 somewhat, 3 quite"
                " a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Emotional well-being Q2 (satisfied with coping re illness) (0"
                " not at all, 1 a little bit, 2 somewhat, 3 quite a bit, 4"
                " very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "e_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Emotional well-being Q1 (sad) (0 not at all, 1 a little bit,"
                " 2 somewhat, 3 quite a bit, 4 very much)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("eq5d5l", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5 (anxiety/depression) (1 not - 5 extremely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4 (pain/discomfort) (1 none - 5 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (usual activities) (1 no problems - 5 unable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2 (self-care) (1 no problems - 5 unable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1 (mobility) (1 no problems - 5 unable)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "health_vas",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Visual analogue scale for overall health (0 worst - 100 best)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("epds", schema=None) as batch_op:
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )

    with op.batch_alter_table("distressthermometer", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="9. depression (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="8. close friend/relative (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="7. partner (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="6. children (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="5. work/school (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="4. transportation (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q36",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="36. tingling in hands/feet (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q35",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="35. sleep (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q34",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="34. skin dry/itchy (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q33",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="33. sexual (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="32. pain (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="31. nose dry/congested (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="30. nausea (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="3. insurance/financial (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="29. mouth sores (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="28. memory/concentration (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="27. indigestion (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="26. getting around (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="25. fevers (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="24. feeling swollen (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="23. fatigue (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="22. eating (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="21. diarrhoea (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="20. constipation (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="2. housing (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="19. urination (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="18. breathing (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="17. bathing/dressing (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="16. appearance (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="15. spiritual/religious (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="14. loss of interest (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="13. worry (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="12. sadness (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="11. nervousness (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="10. fears (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="1. child care (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Other problems",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Distress (0 none - 10 extreme)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "diagnosis_icd9cm_item", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "seqnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Sequence number (consistently 1-based as of 2018-12-01)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "diagnosis_icd9cm_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to parent table",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Description of the diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "code",
            existing_type=sa.String(length=7),
            comment=None,
            existing_comment="Diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("diagnosis_icd9cm", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "relates_to_date",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date that diagnoses relate to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("diagnosis_icd10_item", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "seqnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Sequence number (consistently 1-based as of 2018-12-01)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "diagnosis_icd10_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to parent table",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Description of the diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "code",
            existing_type=sa.String(length=7),
            comment=None,
            existing_comment="Diagnostic code",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("diagnosis_icd10", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "relates_to_date",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Date that diagnoses relate to",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("demqolproxy", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9. irritable (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8. lively (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7. distressed (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6. content (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5. sad (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4. full of energy (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32. Overall quality of life (1 very good - 4 poor; -99 no"
                " response)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31. worried: physical health (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30. worried: not playing a useful part (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3. frustrated (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29. worried: not being able to help others (1 a lot - 4 not"
                " at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28. worried: not enough company (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27. worried: getting in touch with people (1 a lot - 4 not"
                " at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26. worried: taking longer (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25. worried: looking after finances (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24. worried: using money to pay (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23. worried: shopping (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22. worried: keeping self looking nice (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21. worried: keeping clean (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20. worried: making self understood (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2. worried/anxious (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19. worried: difficulty making decisions (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18. worried: muddled (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17. worried: forget day (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16. worried: forget place (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15. worried: forget people (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14. worried: forget recent (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13. worried: forget distant (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12. worried: memory in general (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11. things to look forward to (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10. fed up (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1. cheerful (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("demqol", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9. distressed (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8. lonely (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7. sad (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6. full of energy (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5. confident (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4. frustrated (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3. enjoying life (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29. Overall quality of life (1 very good - 4 poor; -99 no"
                " response)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28. worried: health overall (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27. worried: feel in self (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26. worried: toilet (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25. worried: getting help (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24. worried: making self understood (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23. worried: people not listening (1 a lot - 4 not at all;"
                " -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22. worried: affection (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21. worried: get on with people close (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20. worried: not enough company (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2. worried/anxious (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19. worried: poor concentration (1 a lot - 4 not at all; -99"
                " no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18. worried: difficulty making decisions (1 a lot - 4 not at"
                " all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17. worried: muddled (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16. worried: forget day (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15. worried: forget people (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14. worried: forget recent (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13. couldn't do things (1 a lot - 4 not at all; -99 no"
                " response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12. fed up (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11. irritable (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10. lively (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1. cheerful (1 a lot - 4 not at all; -99 no response)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("demoquestionnaire", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "deakin_1_healthreview", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "willing_to_participate_in_further_studies",
            existing_type=sa.Boolean(name="ck_deakin_1_healthreview_wtpifs"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "vaccinations_last3months",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recreational_drug_in_last_3_months",
            existing_type=sa.Boolean(
                name="ck_deakin_1_healthreview_recdruglast3mo"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_tobacco_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_tobacco_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_tobacco_cigsperweek",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Tobacco: cigarettes per week",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_methadone_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_methadone_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_mdma_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_mdma_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_legalhighs_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_legalhighs_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_ketamine_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_ketamine_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_inhalants_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_inhalants_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_heroin_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_heroin_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_hallucinogens_prevheavy",
            existing_type=sa.Boolean(
                name="ck_deakin_1_healthreview_hallucinogenprevheavy"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_hallucinogens_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_crack_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_crack_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cocaine_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cocaine_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cannabis_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cannabis_jointsperweek",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Cannabis: joints per week",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_cannabis_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_benzodiazepines_prevheavy",
            existing_type=sa.Boolean(
                name="ck_deakin_1_healthreview_benzoprevheavy"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_benzodiazepines_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_amphetamines_prevheavy",
            existing_type=sa.Boolean(
                name="ck_deakin_1_healthreview_amphetprevheavy"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_amphetamines_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_alcohol_unitsperweek",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Alcohol: units per week",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_alcohol_prevheavy",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recdrug_alcohol_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency (0 did not use, 1 occasionally, 2 monthly, 3"
                " weekly, 4 daily)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "other_relevant_things",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_worked_with_metal",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_tattoos_nicotine_patches",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_previous_brain_scan",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_nonremovable_metal",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_metal_from_operations",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_difficulty_lying_1_hour",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mri_claustrophobic",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infections_last3months",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infections_chronic",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_urinary",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_sexual",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_respiratory",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_hepatitis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_recent_gastroenteritis",
            existing_type=sa.Boolean(
                name="ck_deakin_1_healthreview_inf_recent_gastro"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_urinary",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_sexual",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_respiratory",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_hepatitis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "infection_chronic_gastroenteritis",
            existing_type=sa.Boolean(
                name="ck_deakin_1_healthreview_inf_chronic_gastro"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_sle", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "immunity_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_ms", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "immunity_hiv", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "immunity_graves",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_diabetes",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immunity_arthritis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "immune_disorders",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "health_anything_else",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "handedness",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Handedness (L, R)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_sle",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_psychosis_sz",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_ms",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_graves",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_diabetes",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_bipolar",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "familyhistory_arthritis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "family_history",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnicity_text",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Ethnicity, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnicity_other_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Ethnicity, other, details",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnicity",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Ethnicity code, per GMC Patient Questionnaire (1-16)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergy_pollen_dust",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergy_other", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "allergy_food", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "allergy_dermatitis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergy_dander",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergy_asthma",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "allergies", existing_type=sa.Boolean(), existing_nullable=True
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("dast", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q9. feel bad about drug abuse (-) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q8. blackouts/flashbacks (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q7. try to limit to certain situations (-) ("+" = Y scores 1,'
                ' "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q6. abuse drugs continuously (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q5. stop when want to (-) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q4. get through week without drugs (-) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q3. abused >1 drug at a time (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q28. outpatient treatment for drug abuse (+) ("+" = Y scores'
                ' 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q27. drug treatment program (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q26. hospital for medical problems (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q25. sought help (+) ("+" = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q24. medical problems (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q23. withdrawal symptoms (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q22. arrested for possession (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q21. illegal activities to obtain (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q20. arrested for driving under influence (+) ("+" = Y scores'
                ' 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q2. abused prescription drugs (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q19. arrested for unusual behaviour under influence (+) ("+"'
                ' = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q18. fights under influence (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q17. lost job (+) ("+" = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q16. trouble at work (+) ("+" = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q15. neglected family/missed work (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q14. lost friends (+) ("+" = Y scores 1, "-" = N scores 1)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q13. family sought help (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q12. caused problems with spouse (+) ("+" = Y scores 1, "-" ='
                " N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q11. friends/relative know/suspect (+) ("+" = Y scores 1, "-"'
                " = N scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q10. spouse/parents complain (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                'Q1. non-medical drug use (+) ("+" = Y scores 1, "-" = N'
                " scores 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("dad", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "telephone_plan_dial",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "telephone_plan_dial (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "telephone_init_phone",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "telephone_init_phone (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "telephone_exec_message",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "telephone_exec_message (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "telephone_exec_conversation",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "telephone_exec_conversation (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "outing_plan_outing",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "outing_plan_outing (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_init_outing",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "outing_init_outing (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_exec_return_with_shopping",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "outing_exec_return_with_shopping (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_exec_reach_destination",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "outing_exec_reach_destination (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "outing_exec_mode_transportation",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "outing_exec_mode_transportation (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "medications_init_medication",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "medications_init_medication (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "medications_exec_take_medications",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "medications_exec_take_medications (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mealprep_plan_meal",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "mealprep_plan_meal (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mealprep_init_meal",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "mealprep_init_meal (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mealprep_exec_meal",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "mealprep_exec_meal (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_plan_chores",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "leisure_plan_chores (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_init_interest_leisure",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "leisure_init_interest_leisure (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_init_interest_chores",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "leisure_init_interest_chores (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_exec_safe_at_home",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "leisure_exec_safe_at_home (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leisure_exec_complete_chores",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "leisure_exec_complete_chores (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hygiene_plan_wash",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "hygiene_plan_wash (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_init_wash",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "hygiene_init_wash (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_init_teeth",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "hygiene_init_teeth (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_init_hair",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "hygiene_init_hair (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_exec_wash",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "hygiene_exec_wash (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_exec_teeth",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "hygiene_exec_teeth (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hygiene_exec_hair",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "hygiene_exec_hair (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_plan_pay_bills",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "finance_plan_pay_bills (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_plan_organise_correspondence",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "finance_plan_organise_correspondence (1 yes, 0 no, -99 not"
                " applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_init_interest",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "finance_init_interest (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finance_exec_handle_money",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "finance_exec_handle_money (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eating_plan_utensils",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "eating_plan_utensils (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eating_init_eat",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "eating_init_eat (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "eating_exec_eat",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "eating_exec_eat (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_plan_order",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "dressing_plan_order (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_plan_clothing",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "dressing_plan_clothing (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_init_dress",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "dressing_init_dress (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_exec_undress",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "dressing_exec_undress (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dressing_exec_dress",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "dressing_exec_dress (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "continence_init_toilet",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "continence_init_toilet (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "continence_exec_toilet",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "continence_exec_toilet (1 yes, 0 no, -99 not applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cpft_lps_resetresponseclock", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cpft_lps_referral", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "sensory_impairment",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_aware_of_referral",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "interpreter_required",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_trauma",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_self_harm_not_overdose",
            existing_type=sa.Boolean(name="ck_cpft_lps_referral_arshno"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_poor_adherence",
            existing_type=sa.Boolean(name="ck_cpft_lps_referral_adpa"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_overdose",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_infection",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_falls",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "admission_reason_confusion",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cpft_lps_discharge", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "referral_reason_suicidal_ideas",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_rrsuicidal"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_substance_other",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_substanceother"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_substance_alcohol",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_alcohol"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_somatoform_mus",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_mus"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_self_harm_overdose",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_rrshoverdose"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_self_harm_other",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_rrshother"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_safeguarding",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_psychosis",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_pre_transplant",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_pretransplant"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_post_transplant",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_posttransplant"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_motivation_adherence",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_motivadherence"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_low_mood",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_elevated_mood",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_eating_disorder",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_eatingdis"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_discharge_placement",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_dcplacement"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_delirium",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_cognitive_problem",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_cognitiveprob"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_capacity",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_behavioural_disturbance",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_behavdisturb"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "referral_reason_anxiety",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_wanted_copy_of_letter",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "management_treatment_adherence",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_mx_rx_adhere"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_therapy_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_therapy_cbt",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_therapy_cat",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_supportive_staff",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_supportive_patient",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_supportive_carers",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_specialling_behavioural_disturbance",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_msbd"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_signposting_external_referral",
            existing_type=sa.Boolean(
                name="ck_cpft_lps_discharge_mx_signpostrefer"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_other",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_nursing_management",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s5_2",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s3",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s2",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_mha_s136",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_medication",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_education_staff",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_education_patient",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_education_carers",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_complex_case_conference",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_caseconf"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_capacity",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_assessment_diagnostic",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_mx_ass_diag"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "management_accommodation_placement",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_accom"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "leaflet_or_discharge_card_given",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_lodcg"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "frequent_attender",
            existing_type=sa.Boolean(),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "diagnosis_no_active_mental_health_problem",
            existing_type=sa.Boolean(name="ck_cpft_lps_discharge_nomhprob"),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("core10", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (unhappy) (0 not at all - 4 most or all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (despair/hopelessness) (0 not at all - 4 most or all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (sleep problems) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (suicidality) (0 not at all - 4 most or all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (panic) (0 not at all - 4 most or all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (talking is too much) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (coping) (0 most or all of the time - 4 not at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (support) (0 most or all of the time - 4 not at all)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (unwanted images) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (tension/anxiety) (0 not at all - 4 most or all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cope_brief", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "relationship_to_patient_other",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Relationship of responder to patient (if OTHER chosen)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "relationship_to_patient",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Relationship of responder to patient (0 other, 1 wife, 2"
                " husband, 3 daughter, 4 son, 5 sister, 6 brother, 7 mother, 8"
                " father, 9 friend)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, saying things to let unpleasant feelings escape (0 not at"
                " all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, refusing to believe it's happened (0 not at all - 3 a"
                " lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, taking action to make situation better (0 not at all - 3"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, given up trying to deal with it (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, emotional support from others (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, alcohol/drugs to feel better (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, saying it's unreal (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28, making fun of the situation (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27, praying/meditating (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q26, blaming myself (0 not at all - 3 a lot)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25, thinking hard about what steps to take (0 not at all - 3"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24, learning to live with it (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23, trying to get help/advice from others about what to do"
                " (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22, seeking comfort in religion/spirituality (0 not at all -"
                " 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21, expressing negative feelings (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20, accepting reality of the fact it's happened (0 not at"
                " all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, concentrating efforts on doing something about it (0 not"
                " at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19, doing something to think about it less (0 not at all - 3"
                " a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18, making jokes about it (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17, looking for something good in what's happening (0 not at"
                " all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16, giving up the attempt to cope (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15, getting comfort/understanding from someone (0 not at all"
                " - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14, trying to come up with a strategy (0 not at all - 3 a"
                " lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13, criticizing myself (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, trying to see it in a more positive light (0 not at all"
                " - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, alcohol/drugs to get through it (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, getting help/advice from others (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, work/activities to take mind off (0 not at all - 3 a lot)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by_patient",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Task completed by patient? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "completed_by",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Name of person task completed by (if not by patient)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("contactlog", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "start",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Date/time that contact started",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "staff_liaison",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Liaison with staff involved (0 no, 1 yes)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_contact",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Patient contact involved (0 no, 1 yes)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "other_liaison",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Liaison with others (e.g. family) involved (0 no, 1 yes)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "location",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Location",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "end",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Date/time that contact ended",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ciwa", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "t",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Temperature (degrees C)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sbp",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Systolic blood pressure (mmHg)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rr",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Respiratory rate (breaths/minute)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, headache/fullness in head (0-7, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, visual disturbances (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, auditory disturbances (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, tactile disturbances (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, agitation (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, anxiety (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, paroxysmal sweats (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, tremor (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, orientation/clouding of sensorium (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, nausea/vomiting (0-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hr",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Heart rate (beats/minute)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dbp",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Diastolic blood pressure (mmHg)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cisr", schema=None) as batch_op:
        batch_op.alter_column(
            "worry_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Any worries at all in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Excessive worry in past month? (1 no, 2 sometimes, 3 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worry (about things other than physical health): for how"
                " long? (1: <2 weeks; 2: 2 weeks–6 months; 3: 6 months–1 year;"
                " 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry_cont1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Main source of worry in past week? (1 family members; 2"
                " relationships with friends/colleagues; 3 housing; 4"
                " money/bills; 5 own physical health; 6 own mental health; 7"
                " work/lack of work; 8 legal; 9 political/news)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worry (about things other than physical health) for >3h on"
                " any day in past week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How unpleasant is worry (about things other than physical"
                " health) (1 not at all, 2 a little unpleasant, 3 unpleasant,"
                " 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Worrying too much? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "worry2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worries (about things other than physical health) on how many"
                " days in past week (1: none, 2: one to three, 3: four or"
                " more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "weight5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Weight gain amount (1: ≥0.5 stones; 2: <0.5 stones)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Weight gain in past month (1 yes, 2 no, 3 yes but pregnant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Weight loss amount (1: ≥0.5 stones; 2: <0.5 stones)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Weight loss: trying to lose weight? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "weight1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Weight loss in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Pain: bothersome whilst doing something interesting in past"
                " week? (1 no, 2 yes, 3 haven't done anything interesting)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Pain: unpleasant in past week? (1 not at all, 2 a little"
                " unpleasant, 3 unpleasant, 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Pain: lasted >3h on any day in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Pain: days in past week (1: none, 2: one to three, 3: four or"
                " more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_pain1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Pain/ache brought on or made worse because"
                " low/anxious/stressed (1 never, 2 sometimes, 3 always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Bodily discomfort in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Any aches/pains in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Duration of ache/pain/discomfort (1: <2 weeks; 2: 2 weeks–6"
                " months; 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Discomfort: bothersome whilst doing something interesting in"
                " past week? (1 no, 2 yes, 3 haven't done anything"
                " interesting)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Discomfort: unpleasant in past week? (1 not at all, 2 a"
                " little unpleasant, 3 unpleasant, 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Discomfort: lasted >3h on any day in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Discomfort: days in past week (1: none, 2: one to three, 3:"
                " four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "somatic_dis1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Discomfort brought on or made worse because"
                " low/anxious/stressed (1 never, 2 sometimes, 3 always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Problems with excess sleep in past month (1 no, 2 slept more"
                " than usual but not a problem, 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Problems with sleep loss in past month (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_lose3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "On how many nights in past week did you spend >=3h trying to"
                " get to sleep? (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_lose2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "On night with least sleep in past week, how long trying to"
                " get to sleep? (1: <15min, 2: 15–60min, 3: 1–3h, 4: >=3h)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_lose1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Sleep loss: nights in past week with problems (1: none, 2:"
                " one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_gain3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "On how many nights in past week did you sleep >3h longer than"
                " usual? (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_gain2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "On night with most sleep in past week, how much more than"
                " usual? (1: <15min, 2: 15–60min, 3: 1–3h, 4: >=3h)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_gain1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Sleep gain: how many nights in past week (1: none, 2: one to"
                " three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_emw",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Woken >2h earlier (and couldn't return to sleep) in past"
                " week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "How long have you had these problems with sleep? (1: <2"
                " weeks; 2: 2 weeks–6 months; 3: 6 months–1 year; 4: 1–2"
                " years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sleep_cause",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "What are your sleep difficulties caused by? (1 noise, 2 shift"
                " work, 3 pain/illness, 4 worries, 5 unknown, 6 other"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias_type1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Which phobia? (1 travelling alone by bus/train; 2 being far"
                " from home; 3 public eating/speaking; 4 sight of blood; 5"
                " crowded shops; 6 insects/spiders/animals; 7 being watched; 8"
                " enclosed spaces or heights; 9 something else)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias_mand",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Phobic avoidance in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Phobic anxiety: for how long? (1: <2 weeks; 2: 2 weeks–6"
                " months; 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Phobic avoidance: how many times in past week? (1: none, 2:"
                " 1–3, 3: >=4)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Phobic avoidance in past week? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Phobic anxiety: physical symptoms in past week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "phobias1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Phobic anxiety: days in past week (1: none, 2: one to three,"
                " 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "pansym_m",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: hot flushes/chills (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_l",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: tingling/numbness (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_k",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: fear were dying (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_j",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: losing control/going crazy (1 no,"
                " 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_i",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: derealization/depersonalization"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_h",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: dizzy/unsteady/lightheaded/faint"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_g",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: nausea (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_f",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: chest pain/pressure/discomfort (1"
                " no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_e",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: choking sensation (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_d",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: short of breath (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_c",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: trembling/shaking (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_b",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: hands sweaty/clammy (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pansym_a",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic symptom in past week: heart racing (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic_mand",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic in past month (1: no, my anxiety never got that bad; 2:"
                " yes, sometimes; 3: yes, often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic: for how long? (1: <2 weeks; 2: 2 weeks–6 months; 3: 6"
                " months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Is panic always brought on by specific things? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Do panics start suddenly? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic: in the past week, did the worst panic last >10min (1:"
                " <10min; 2 >=10min)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic: how unpleasant in past week (1 a little uncomfortable;"
                " 2 unpleasant; 3 unbearable, or very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "panic1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Panic: how often in past week (1 not in past seven days, 2"
                " once, 3 more than once)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "overall2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Overall impact on normal activities in past week (1 not at"
                " all; 2 they have made things more difficult but I get"
                " everything done; 3 they have stopped one activity; 4 they"
                " have stopped >1 activity)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Obsessions: same thoughts repeating or general worries (1"
                " same thoughts over and over, 2 worrying about something in"
                " general)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Obsessions in past month (1 no, 2 sometimes, 3 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Obsessions: for how long? (1: <2 weeks; 2: 2 weeks–6 months;"
                " 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Obsessions: longest time spent thinking these thoughts, in"
                " past week (1: <15min; 2: >=15min)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Obsessions: upsetting/annoying in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Obsessions: tried to stop in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "obsess1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Obsessions: how many days in past week (1: none, 2: one to"
                " three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "married",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(Demographics) Marital status (1 married/living as married, 2"
                " single, 3 separated, 4 divorced, 5 widowed, 6 prefer not to"
                " say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Short-tempered/angry over trivial things in past month? (1"
                " no, 2 sometimes, 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Irritable with those around you in past month? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Irritable/short-tempered/angry: for how long? (1: <2 weeks;"
                " 2: 2 weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "In past week, have you had arguments/rows/lost temper? (1 no;"
                " 2 yes but justified; 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Irritable/short-tempered/angry: wanted to shout at someone?"
                " (1 no; yes but didn't shout; 3 yes and did shout)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Irritable/short-tempered/angry: for >1h on any day in past"
                " week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "irrit1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Irritable/short-tempered/angry: days in past week (1: none,"
                " 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "illness",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Conditions (1 diabetes, 2 asthma, 3 arthritis, 4 heart"
                " disease, 5 high blood pressure, 6 lung disease, 7 more than"
                " one of the above, 8 none of the above)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hypo_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Do you worry you have a serious illness? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worried about physical health in past month? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worrying about physical health: for how long? (1: <2 weeks;"
                " 2: 2 weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Able to take mind off health worries in past week? (1 yes,"
                " 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worrying about health: how unpleasant? (1 not at all, 2 a"
                " little unpleasant, 3 unpleasant, 4 very unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worrying too much about physical health? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hypo1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Worrying about health/having a serious illness: how many days"
                " in past week? (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "home",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(Demographics) Housing situation (1 home owner, 2 tenant, 3"
                " living with relative/friend, 4 hostel/care home, 5 homeless,"
                " 6 other,7 prefer not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "gp_year",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Consultations with GP in past year (0: none, 1: 1–2, 2: 3–4,"
                " 3: 6–10; 4: >10"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "forget_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Problems with memory: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Tired during an enjoyable activity (1 no, 2 yes, 3 haven't"
                " done anything enjoyable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "So tired you've had to push yourself to get things done in"
                " past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Tired: >3h on any one day in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_tired1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Tired: days in past week (1: none, 2: one to three, 3: four"
                " or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Lacking in energy in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Tired in past month (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Lacking energy during an enjoyable activity (1 no, 2 yes, 3"
                " haven't done anything enjoyable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "So lacking in energy you've had to push yourself to get"
                " things done in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Lacking energy: for >3h on any one day in past week (1 no, 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_energy1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Lacking energy: days in past week (1: none, 2: one to three,"
                " 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Feeling tired/lacking energy for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_cause2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Main reason for lacking energy (1 problems with sleep; 2"
                " medication; 3 physical illness; 4 working too hard inc."
                " childcare; 5 stress/worry/other psychological; 6 physical"
                " exercise; 7 other; 8 don't know)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fatigue_cause1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Main reason for feeling tired (1 problems with sleep; 2"
                " medication; 3 physical illness; 4 working too hard inc."
                " childcare; 5 stress/worry/other psychological; 6 physical"
                " exercise; 7 other; 8 don't know)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ethnic",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(Demographics) Ethnicity (1 white, 2 mixed, 3 Asian/British"
                " Asian, 4 Black/Black British, 5 Chinese, 6 other, 7 prefer"
                " not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "emptype",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(Demographics) Current/last paid employment (1 self-employed"
                " with paid employees, 2 self-employed with no paid employees,"
                " 3 employee, 4 foreman/supervisor, 5 manager, 6 not"
                " applicable,7 prefer not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "empstat",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(Demographics) Current employment status (1 working full"
                " time, 2 working part time, 3 student, 4 retired, 5"
                " houseperson, 6 unemployed job seeker, 7 unemployed due to"
                " ill health,8 prefer not to say)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "doctor",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Have you spoken to your doctor about these thoughts of"
                " killing yourself (1 yes; 2 no, but have talked to other"
                " people; 3 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "disable",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Longstanding illness/disability/infirmity (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Thoughts of suicide in past week (1 no; 2 yes, but would"
                " never commit suicide; 3 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Life not worth living in past week (1 no, 2 sometimes, 3"
                " always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Hopeless in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Feeling not as good as other people in past week (1 no, 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Guilt/blamed self in past week (1 never, 2 only when it was"
                " my fault, 3 sometimes, 4 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Psychomotor retardation in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Restlessness in past week (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Libido in past month (1 not applicable, 2 no change, 3"
                " increased, 4 decreased)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Thoughts of way to kill self in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depth1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Diurnal mood variation in past week (1 worse in the morning,"
                " 2 worse in the evening, 3 varies, 4 no difference)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "In the past month, able to enjoy/take an interest in things"
                " as much as usual? (1 yes; 2 no, less enjoyment than usual; 3"
                " no, don't enjoy anything)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Sad/miserable/depressed in past month? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Depressed mood/anhedonia: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr_content",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Main reason for [depressed mood] or [anhedonia]? (1 family"
                " members; 2 relationships with friends/colleagues; 3 housing;"
                " 4 money/bills; 5 own physical health; 6 own mental health; 7"
                " work/lack of work; 8 legal; 9 political/news)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "In past week, during [depressed mood] or [anhedonia], did"
                " nice things/company make you happier? (1 always, 2"
                " sometimes, 3 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "[Depressed mood] or [anhedonia] for >3h on any day in past"
                " week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "[Depressed mood] or [anhedonia] on how many days in past week"
                " (1: none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "In the past week, able to enjoy/take an interest in things as"
                " much as usual? (1 yes; 2 no, less enjoyment than usual; 3"
                " no, don't enjoy anything)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "depr1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Sad/miserable/depressed in past week? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Problems with forgetting things during past month? (1 no, 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Problems in concentrating during past monnth? (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Problems with concentration: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Forgotten anything important in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Problems with concentration have stopped you from getting on"
                " with things in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "In past week, could concentrate on all of: TV, newspaper,"
                " conversation (1 yes, 2 no)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "conc1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Concentration/memory problems: days in past week (1: none, 2:"
                " one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Compulsions in past month (1 no, 2 sometimes, 3 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Compulsions: for how long? (1: <2 weeks; 2: 2 weeks–6 months;"
                " 3: 6 months–1 year; 4: 1–2 years; 5: >2 years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Compulsions: greatest number of repeats in past week (1:"
                " once, i.e. two times altogether; 2: two repeats; 3: three or"
                " more repeats)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Compulsions: upsetting/annoying in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Compulsions: tried to stop in past week (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comp1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Compulsions: how many days in past week (1: none, 2: one to"
                " three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "appetite2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Marked increase in appetite in past month (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "appetite1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Marked appetite loss in past month (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_phobia2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Phobic anxiety: always specific? (1 always specific, 2"
                " sometimes general)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_phobia1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Phobic anxiety in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_mand2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Muscle tension/couldn't relax in past month? (1 no, 2"
                " sometimes, 3 often)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_mand1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Anxious/nervous in past month? (1 no, 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx_dur",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Anxiety/nervousness/tension: for how long? (1: <2 weeks; 2: 2"
                " weeks–6 months; 3: 6 months–1 year; 4: 1–2 years; 5: >2"
                " years)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Anxiety/nervousness/tension: for >3h on any day in past week?"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Anxiety/nervousness/tension: physical symptoms in past week?"
                " (1 no, 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Anxiety/nervousness/tension: how unpleasant in past week (1"
                " not at all, 2 a little unpleasant, 3 unpleasant, 4 very"
                " unpleasant)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "anx2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Anxiety/nervousness/tension: how many days in past week (1:"
                " none, 2: one to three, 3: four or more)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cgisch", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "severity5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Severity Q5, overall (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Severity Q4, cognitive (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Severity Q3, depressive (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Severity Q2, negative (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "severity1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Severity Q1, positive (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Change Q5, overall (1-7, higher worse, or 9 N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Change Q4, cognitive (1-7, higher worse, or 9 N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Change Q3, depressive (1-7, higher worse, or 9 N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Change Q2, negative (1-7, higher worse, or 9 N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "change1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Change Q1, positive (1-7, higher worse, or 9 N/A)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cgi_i", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Global improvement (1-7, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cgi", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q3t",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3T. Therapeutic effects (1-4, higher worse, 0 not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3s",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3S. Side effects (1-4, higher worse, 0 not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (calculated). Efficacy index [(Q3T - 1) * 4 + Q3S]."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2. Global improvement (1-7, higher worse, 0 not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1. Severity (1-7, higher worse, 0 not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cesdr", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (felt a bad person) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (nothing made me happy) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (could not get going) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (sad) (0 not at all - 4 nearly every day for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (sleep restless) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (depressed) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (poor concentration) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (lack of focus) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (unshakable blues) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (difficulty getting to sleep) (0 not at all - 4 nearly"
                " every day for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (unintended weight loss) (0 not at all - 4 nearly every"
                " day for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (disliked self) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (tiredness) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (wanted to hurt self) (0 not at all - 4 nearly every day"
                " for two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (wished were dead) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (fidgety) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (moving slowly) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (oversleeping) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (loss of interest) (0 not at all - 4 nearly every day for"
                " two weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (poor appetite) (0 not at all - 4 nearly every day for two"
                " weeks)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cesd", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (feelings of failure) (0 rarely/none of the time - 4 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (hopeful) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (everything effortful) (0 rarely/none of the time - 4 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (depressed) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (poor concentration) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (low self-esteem) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (unshakeable blues) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (could not get going) (0 rarely/none of the time - 4 all"
                " of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (poor appetite) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (feeling disliked) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (sadness) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (crying spells) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (enjoyment) (0 rarely/none of the time - 4 all of the"
                " time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (perceived unfriendliness) (0 rarely/none of the time - 4"
                " all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (lonely) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (uncommunicative) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (happy) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (sleep restless) (0 rarely/none of the time - 4 all of"
                " the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (fearful) (0 rarely/none of the time - 4 all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (sensitivity/irritability) (0 rarely/none of the time - 4"
                " all of the time)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cecaq3", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "s6_upsetting_sexual_adult_authority",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Upsetting sexual experiences under 17yo with related adult or"
                " someone in authority (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_unwanted_sexual_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Sexual abuse, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_unwanted_intercourse",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Unwanted intercourse before 17yo (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_touch_privates_subject",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, other experience, touched your private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_touch_privates_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, other experience, touched their private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_relative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, other experience, person was a relative?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_person_known",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, other experience, knew the person?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_more_than_once",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, other experience, happened more than once?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_intercourse",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, other experience, sexual intercourse?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_in_household",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, other experience, person lived in household?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_other_age",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Sexual abuse, other experience, age it began",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_touch_privates_subject",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, first experience, touched your private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_touch_privates_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, first experience, touched their private parts?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_relative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, first experience, person was a relative?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_person_known",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, first experience, knew the person?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_more_than_once",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, first experience, happened more than once?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_intercourse",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, first experience, sexual intercourse?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_in_household",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Sexual abuse, first experience, person lived in household?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_first_age",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Sexual abuse, first experience, age it began",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s6_any_unwanted_sexual_experience",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Any unwanted sexual experiences (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_physicalabuse",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_parental_abuse_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Physical abuse, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_nonparent_abuse_description",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Physical abuse, nonparent, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_out_of_control",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by mother, out of control?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_injured",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by mother, injured?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_hit_more_than_once",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by mother, hit on >1 occasion",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_hit_how",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical abuse, by mother, hit how (1 belt/stick, 2"
                " punched/kicked, 3 hit with hand, 4 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_mother_abuse_age_began",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Physical abuse, by mother, age began (y)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_out_of_control",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by father, out of control?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_injured",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by father, injured?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_hit_more_than_once",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by father, hit on >1 occasion",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_hit_how",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Physical abuse, by father, hit how (1 belt/stick, 2"
                " punched/kicked, 3 hit with hand, 4 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_father_abuse_age_began",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Physical abuse, by father, age began (y)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_abused_by_mother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_abused_by_father",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s5c_abuse_by_nonparent",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Physical abuse, by anyone else in household?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_sibling",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Two closest people include: sibling?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_otherrelative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Two closest people include: other relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Two closest people include: other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Two closest people include: other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_mother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Two closest people include: mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_father",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Two closest people include: father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_childfriend",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Two closest people include: friend your age?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_adultfriend",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Two closest people include: adult family friend?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4c_closest_additional",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Two closest people include: additional notes",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_sister",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Child confidant, sister?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_otherrelative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Child confidant, other relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_otherfriend",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Child confidant, other less close friend(s)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Child confidant, other person, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Child confidant, other person?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_closefriend",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Child confidant, close friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_brother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Child confidant, brother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant_additional",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Child confidant, additional notes",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4b_childconfidant",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Child confidant?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_responsibleadult",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Adult confidant, teacher/vicar/etc.?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_otherrelative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Adult confidant, other relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Adult confidant, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Adult confidant, other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_mother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Adult confidant, mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_father",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Adult confidant, father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_familyfriend",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Adult confidant, family friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant_additional",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Adult confidant, additional notes",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s4a_adultconfidant",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Adult confidant?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_which_parent_cared_for",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Which parent did you have to provide care for (0 none, 1"
                " mother, 2 father, 3 both, 4 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Parents coped if you were hurt/ill (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Parents looked to you for help (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Parents said they couldn't cope (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Miss seeing friends for domestic responsibilities (1 no - 5"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Miss school for domestic responsibilities (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Cooking/cleaning (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Look after young siblings (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Housework (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Had to keep secrets for parent (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Parents made you feel guilty for their sacrifices (1 no - 5"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Try to make parent smile when upset (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Tried to support/care for parent (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Concerned/worried re parent (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Parents cried in front of you (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Parents relied on you for emotional support (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Parents confided their problems (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Responsibility (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_parent_physical_problem",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Parent/s had disability/physical illness (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3c_parent_mental_problem",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Parent/s had emotional/mental health problems (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q9_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, rejecting (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q8_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, shamed me before others (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q7_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, humiliated me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q6_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, liked to see me suffer (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q5_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, played on fears (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q4_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, contradictory (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q3_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, undermined confidence (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q2_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, made me keep secrets (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q1_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q17_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, said wanted me dead (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q16_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, forced to break law (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q15_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, threatened to hurt people dear to me (0 no - 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q14_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, obedience through guilt (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q13_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, wouldn't let me mix (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q12_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, deprived light/food/company (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q11_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, eat disliked until sick (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q10_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, took things I cherished (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, tease me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_extra",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3b_age_began",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Age these experienced began (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_which_father_figure_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Father figure, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_which_father_figure",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, which one (0 none/skip, 1 birth father, 2"
                " stepfather, 3 other relative, 4 other non-relative, 5 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, nuisance (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, time to talk (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, unsupervised <10y (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, critical (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, better when upset (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, made me feel unwanted (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, interested re school (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, concerned re my worries (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, preferred siblings (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, neglected basic needs (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, cared when ill (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, concerned re whereabouts (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, interested in friends (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Father figure, there if needed (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, picked on unfairly (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Father figure, difficult to please (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s3a_extra",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Father figure, extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q9_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, rejecting (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q8_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, shamed me before others (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q7_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, humiliated me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q6_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, liked to see me suffer (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q5_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, played on fears (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q4_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, contradictory (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q3_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, undermined confidence (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q2_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, made me keep secrets (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q1_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q17_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, said wanted me dead (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q16_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, forced to break law (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q15_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, threatened to hurt people dear to me (0 no - 2"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q14_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, obedience through guilt (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q13_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, wouldn't let me mix (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q12_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, deprived light/food/company (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q11_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, eat disliked until sick (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q10_frequency",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency (0 never - 3 often)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, took things I cherished (0 no - 2 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, tease me (0 no - 2 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_extra",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2b_age_began",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Age these experienced began (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_which_mother_figure_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Mother figure, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_which_mother_figure",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, which one (0 none/skip, 1 birth mother, 2"
                " stepmother, 3 other relative, 4 other non-relative, 5 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, nuisance (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, time to talk (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, unsupervised <10y (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, critical (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, better when upset (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, made me feel unwanted (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, interested re school (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, concerned re my worries (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, preferred siblings (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, neglected basic needs (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, cared when ill (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, concerned re whereabouts (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, interested in friends (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Mother figure, there if needed (1 no - 5 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, picked on unfairly (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Mother figure, difficult to please (1 no - 5 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s2a_extra",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Mother figure, extra detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_separated_from_mother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Separated from mother for >=1y before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_separated_from_father",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Separated from father for >=1y before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_separation_reason",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Maternal separation, reason (1 illness, 2 work, 3"
                " divorce/separation, 4 never knew, 5 abandoned, 6 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_how_long_first_separation_years",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Maternal separation, how long first separation (y)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_died_subject_aged",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Age when mother died (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_mother_died",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Mother died before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_first_separated_from_mother_aged",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Maternal separation, age (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_first_separated_from_father_aged",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Paternal separation, age (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_separation_reason",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Paternal separation, reason (1 illness, 2 work, 3"
                " divorce/separation, 4 never knew, 5 abandoned, 6 other)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_how_long_first_separation_years",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "Paternal separation, how long first separation (y)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_died_subject_aged",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Age when father died (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_father_died",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Father died before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1c_describe_experience",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Loss of/separation from parent, description",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1b_institution_time_years",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="In institution, time (years)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1b_institution",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="In institution before 17?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_stepmother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, maternal, stepmother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Raised by, maternal, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, maternal, other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_fostermother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, maternal, foster mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_femalerelative_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Raised by, maternal, female relative, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_femalerelative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, maternal, female relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_familyfriend",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, maternal, family friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_birthmother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, maternal, birth mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_motherfigure_adoptivemother",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, maternal, adoptive mother?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_stepfather",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, paternal, stepfather?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_other_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Raised by, paternal, other, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_other",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, paternal, other?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_malerelative_detail",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Raised by, paternal, male relative, detail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_malerelative",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, paternal, male relative?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_fosterfather",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, paternal, foster father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_familyfriend",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, paternal, family friend?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_birthfather",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, paternal, birth father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "s1a_fatherfigure_adoptivefather",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Raised by, paternal, adoptive father?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "any_other_comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Any other comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cbir", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "frequency9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q9, everyday: electrical appliances (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q8, memory: confused in unusual surroundings (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q7, memory: forgets day (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q6, memory: poor concentration (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q5, memory: forgets names of objects (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency45",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q45, motivation: reduced affection (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency44",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q44, motivation: indifferent to family/friend"
                " concerns (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency43",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q43, motivation: fails to contact friends/family"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency42",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q42, motivation: no interest in new things (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency41",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q41, motivation: less enthusiasm in usual interests"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency40",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q40, stereotypy/motor:  expression/catchphrase"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q4, memory: forgets familiar names (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency39",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q39, stereotypy/motor: preoccupied with time (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency38",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q38, stereotypy/motor: routines (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency37",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q37, stereotypy/motor: rigid/fixed opinions (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency36",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q36, sleep: daytime sleep increased (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency35",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q35, sleep: disturbed at night (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency34",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q34, eating: table manners (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency33",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q33, eating: increased appetite (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q32, eating: repetitive (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q31, eating: sweet tooth (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q30, beliefs: delusions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q3, memory: loses things (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q29, beliefs: auditory hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q28, beliefs: visual hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q27, mood: irritable (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q26, mood: restless/agitated (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q25, mood: sad/depressed (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Frequency Q24, mood: cries (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q23, behaviour: impulsive (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q22, behaviour: tactless/suggestive (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q21, behaviour: socially embarrassing (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q20, behaviour: uncooperative (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q2, memory: asks same questions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q19, behaviour: temper outbursts (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q18, behaviour: inappropriate humour (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q17, self-care: bathing (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q16, self-care: feeding (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q15, self-care: dressing (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q14, self-care: grooming (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q13, everyday: money (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q12, everyday: making hot drink (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q11, everyday: using telephone (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q10, everyday: writing (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Frequency Q1, memory: poor day to day memory (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q9, everyday: electrical appliances (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q8, memory: confused in unusual surroundings (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q7, memory: forgets day (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q6, memory: poor concentration (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q5, memory: forgets names of objects (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress45",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q45, motivation: reduced affection (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress44",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q44, motivation: indifferent to family/friend"
                " concerns (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress43",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q43, motivation: fails to contact friends/family"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress42",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q42, motivation: no interest in new things (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress41",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q41, motivation: less enthusiasm in usual interests"
                " (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress40",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q40, stereotypy/motor:  expression/catchphrase (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q4, memory: forgets familiar names (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress39",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q39, stereotypy/motor: preoccupied with time (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress38",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q38, stereotypy/motor: routines (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress37",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q37, stereotypy/motor: rigid/fixed opinions (0-4,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress36",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q36, sleep: daytime sleep increased (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress35",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q35, sleep: disturbed at night (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress34",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q34, eating: table manners (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress33",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q33, eating: increased appetite (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q32, eating: repetitive (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q31, eating: sweet tooth (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q30, beliefs: delusions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q3, memory: loses things (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q29, beliefs: auditory hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q28, beliefs: visual hallucinations (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q27, mood: irritable (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q26, mood: restless/agitated (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q25, mood: sad/depressed (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Distress Q24, mood: cries (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q23, behaviour: impulsive (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q22, behaviour: tactless/suggestive (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q21, behaviour: socially embarrassing (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q20, behaviour: uncooperative (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q2, memory: asks same questions (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q19, behaviour: temper outbursts (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q18, behaviour: inappropriate humour (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q17, self-care: bathing (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q16, self-care: feeding (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q15, self-care: dressing (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q14, self-care: grooming (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q13, everyday: money (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q12, everyday: making hot drink (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q11, everyday: using telephone (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q10, everyday: writing (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Distress Q1, memory: poor day to day memory (0-4, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "confirm_blanks",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Respondent confirmed that blanks are deliberate (N/A) (0/NULL"
                " no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Additional comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdetthreshold_trials", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "yes",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Subject chose YES? (0 didn't, 1 did)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial_num_in_calculation_sequence",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Trial number as used for threshold calculation",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial_ignoring_catch_trials",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Trial number, ignoring catch trials (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Trial number (0-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "target_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Target presentation time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_presented",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Target presented? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Time of response (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_latency_ms",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Response latency (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "responded",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Responded? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "no",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Subject chose NO? (0 didn't, 1 did)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Target intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "choice_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Time choice offered (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "caught_out_reset",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Caught out on catch trial, thus reset? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cardinal_expdetthreshold_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to CardinalExpDetThreshold",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdetthreshold", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "visual_target_duration_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Visual target duration (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "theta",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X)); theta = -intercept/k ="
                " -intercept/slope"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Target number (within available targets of that modality)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_filename",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Filename of media used for target",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_intensity_min",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Minimum starting intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_intensity_max",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Maximum starting intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "slope",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X))"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "prompt",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Prompt given to subject",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "p_catch_trial",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Probability of catch trial",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "num_trials_in_main_sequence",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of trials required in main sequence",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "modality",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Modality (0 auditory, 1 visual)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "main_small_intensity_step",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Main, small, intensity step (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "k",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X)); k = slope"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Intertrial interval (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intercept",
            existing_type=sa.Float(),
            comment=None,
            existing_comment=(
                "logits: L(X) = intercept + slope * X; probability: P = 1 / (1"
                " + exp(-intercept - slope * X))"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "initial_large_intensity_step",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Initial, large, intensity step (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finished",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Subject finished successfully (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "background_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Intensity of background (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "background_filename",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Filename of media used for background",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdet_trials", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Trial start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial_end_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Trial end time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "trial",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Trial number (0-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "target_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Target start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_present",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Target present? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Target number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_modality",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Target modality (0 auditory, 1 visual)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Response time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "response_latency_ms",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Response latency (ms)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "responded",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Responded? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "raw_cue_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Raw cue number (following counterbalancing) (0-based)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rating",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Rating (0 definitely not - 4 definitely)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "points",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Points earned this trial",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Pause start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_given_before_trial",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Pause given before trial? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_end_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Pause end time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Intertrial interval start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_length_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Intertrial interval (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_end_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Intertrial interval end time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "group_num",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Group number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "detection_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Detection response start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cumulative_points",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Cumulative points earned",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cue_start_time",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Cue start time (ISO-8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cue",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Cue number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "correct",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Correct side of the middle rating? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cardinal_expdet_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to cardinal_expdet",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "block",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Block number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "cardinal_expdet_trialgroupspec", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_number",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Target number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "target_modality",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Target modality (0 auditory, 1 visual)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_target",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of trials with target present",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "n_no_target",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of trials with target absent",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "group_num",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Group number (0-based)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "cue",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Cue number (0-based)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cardinal_expdet_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="FK to cardinal_expdet",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cardinal_expdet", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "visual_target_duration_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Visual target duration (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_target_1_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Visual target 1 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_target_0_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Visual target 0 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_cue_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Visual cue intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "visual_background_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Visual background intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "stimulus_counterbalancing",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Stimulus counterbalancing condition",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "pause_every_n_trials",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Pause every n trials",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "num_blocks",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of blocks",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_trial_completed",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of last trial completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_min_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Intertrial interval minimum (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "iti_max_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Intertrial interval maximum (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "isi_duration_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Interstimulus interval (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "is_detection_response_on_right",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                'Is the "detection" response on the right? (0 no, 1 yes)'
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finished",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Was the task finished? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cue_duration_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Cue duration (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_target_1_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Auditory target 1 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_target_0_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Auditory target 0 intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_cue_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Auditory cue intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "auditory_background_intensity",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="Auditory background intensity (0.0-1.0)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "aborted",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Was the task aborted? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("caps", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "intrusiveness9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (body changing shape): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (unexplained smells): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (thoughts spoken aloud): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (hear noises/sounds): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (burning or other bodily sensations): intrusiveness (1 low"
                " - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (see shapes/lights/colours): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32 (hear sounds/music that others cannot): intrusiveness (1"
                " low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31 (see things that others cannot): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30 (food/drink tastes unusual): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (heard thoughts echoed): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29 (smells or odours that others are unaware of):"
                " intrusiveness (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28 (hear voices conversing): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27 (altered perception of time): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26 (everyday things look abnormal): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25 (common smells seem different): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24 (feeling of being uplifted): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23 (lights/colours more intense): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22 (face looks different): intrusiveness (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (tastes stronger than normal): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (hypersensitive to touch/temperature): intrusiveness (1"
                " low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (presence of another): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (shapes/people distorted): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (odours strong): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (hard to distinguish sensations): intrusiveness (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (sounds distorted): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (sensations flooding): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (unexplained tastes): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (hearing words or sentences): intrusiveness (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (feeling a touch): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (voices commenting): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (limbs not own): intrusiveness (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "intrusiveness1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (sounds loud): intrusiveness (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "frequency9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (body changing shape): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (unexplained smells): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (thoughts spoken aloud): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (hear noises/sounds): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (burning or other bodily sensations): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (see shapes/lights/colours): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32 (hear sounds/music that others cannot): frequency (1 low"
                " - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31 (see things that others cannot): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30 (food/drink tastes unusual): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (heard thoughts echoed): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29 (smells or odours that others are unaware of): frequency"
                " (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28 (hear voices conversing): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27 (altered perception of time): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26 (everyday things look abnormal): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25 (common smells seem different): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24 (feeling of being uplifted): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23 (lights/colours more intense): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22 (face looks different): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (tastes stronger than normal): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (hypersensitive to touch/temperature): frequency (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (presence of another): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (shapes/people distorted): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (odours strong): frequency (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (hard to distinguish sensations): frequency (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (sounds distorted): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (sensations flooding): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (unexplained tastes): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (hearing words or sentences): frequency (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (feeling a touch): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (voices commenting): frequency (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (limbs not own): frequency (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (sounds loud): frequency (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (body changing shape): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (unexplained smells): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (thoughts spoken aloud): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (hear noises/sounds): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (burning or other bodily sensations): endorsed? (0 no, 1"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (see shapes/lights/colours): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32 (hear sounds/music that others cannot): endorsed? (0 no,"
                " 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31 (see things that others cannot): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30 (food/drink tastes unusual): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (heard thoughts echoed): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29 (smells or odours that others are unaware of): endorsed?"
                " (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28 (hear voices conversing): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27 (altered perception of time): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26 (everyday things look abnormal): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25 (common smells seem different): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24 (feeling of being uplifted): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23 (lights/colours more intense): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22 (face looks different): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (tastes stronger than normal): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (hypersensitive to touch/temperature): endorsed? (0 no, 1"
                " yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (presence of another): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (shapes/people distorted): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q18 (odours strong): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (hard to distinguish sensations): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q16 (sounds distorted): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (sensations flooding): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (unexplained tastes): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (hearing words or sentences): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q12 (feeling a touch): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (voices commenting): endorsed? (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10 (limbs not own): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "endorse1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1 (sounds loud): endorsed? (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (body changing shape): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (unexplained smells): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (thoughts spoken aloud): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (hear noises/sounds): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (burning or other bodily sensations): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (see shapes/lights/colours): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32 (hear sounds/music that others cannot): distress (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31 (see things that others cannot): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30 (food/drink tastes unusual): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (heard thoughts echoed): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29 (smells or odours that others are unaware of): distress"
                " (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28 (hear voices conversing): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27 (altered perception of time): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26 (everyday things look abnormal): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25 (common smells seem different): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24 (feeling of being uplifted): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23 (lights/colours more intense): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22 (face looks different): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (tastes stronger than normal): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (hypersensitive to touch/temperature): distress (1 low -"
                " 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (presence of another): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (shapes/people distorted): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (odours strong): distress (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (hard to distinguish sensations): distress (1 low - 5"
                " high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (sounds distorted): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (sensations flooding): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (unexplained tastes): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (hearing words or sentences): distress (1 low - 5 high),"
                " if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (feeling a touch): distress (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (voices commenting): distress (1 low - 5 high), if"
                " endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (limbs not own): distress (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (sounds loud): distress (1 low - 5 high), if endorsed"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cape42", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "frequency9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (pessimistic): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (few/no emotions): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (persecuted): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (some people not what they seem): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (magazines/TV personal): frequency? (1 never, 2 sometimes,"
                " 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency42",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q42 (see things others cannot): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency41",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q41 (Capgras): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency40",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q40 (tense): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (not a talker): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency39",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q39 (feel a failure): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency38",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q38 (feel guilty): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency37",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q37 (few hobbies/interests): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency36",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q36 (never get things done): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency35",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q35 (neglecting appearance/hygiene): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency34",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q34 (hear voices conversing): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency33",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q33 (hear voices): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32 (emotions blunted): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31 (controlled by other force): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30 (thought echo): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (not very animated): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29 (lack spontaneity): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28 (others might hear thoughts): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27 (feelings lacking intensity): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26 (thoughts not own): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25 (do nothing): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24 (thoughts removed): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23 (mind empty): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22 (people look oddly because of appearance): frequency? (1"
                " never, 2 sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (lack energy): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (occult): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (double meaning): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (cry about nothing): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (lacking motivation): frequency? (1 never, 2 sometimes, 3"
                " often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (electrical devices influence thinking): frequency? (1"
                " never, 2 sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (no interest being with others): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (telepathy): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (no longer want to live): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (special/unusual person): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (no future): frequency? (1 never, 2 sometimes, 3 often, 4"
                " nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (destined for importance): frequency? (1 never, 2"
                " sometimes, 3 often, 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (conspiracy): frequency? (1 never, 2 sometimes, 3 often,"
                " 4 nearly always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "frequency1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (sad): frequency? (1 never, 2 sometimes, 3 often, 4 nearly"
                " always)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 (pessimistic): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 (few/no emotions): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 (persecuted): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 (some people not what they seem): distress (1 not, 2 a"
                " bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 (magazines/TV personal): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress42",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q42 (see things others cannot): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress41",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q41 (Capgras): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress40",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q40 (tense): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 (not a talker): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress39",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q39 (feel a failure): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress38",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q38 (feel guilty): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress37",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q37 (few hobbies/interests): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress36",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q36 (never get things done): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress35",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q35 (neglecting appearance/hygiene): distress (1 not, 2 a"
                " bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress34",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q34 (hear voices conversing): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress33",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q33 (hear voices): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress32",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q32 (emotions blunted): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress31",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q31 (controlled by other force): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress30",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q30 (thought echo): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 (not very animated): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress29",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q29 (lack spontaneity): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress28",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q28 (others might hear thoughts): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress27",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q27 (feelings lacking intensity): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress26",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q26 (thoughts not own): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress25",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q25 (do nothing): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24 (thoughts removed): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23 (mind empty): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22 (people look oddly because of appearance): distress (1"
                " not, 2 a bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 (lack energy): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 (occult): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 (double meaning): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 (cry about nothing): distress (1 not, 2 a bit, 3 quite, 4"
                " very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 (lacking motivation): distress (1 not, 2 a bit, 3 quite,"
                " 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 (electrical devices influence thinking): distress (1 not,"
                " 2 a bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 (no interest being with others): distress (1 not, 2 a"
                " bit, 3 quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 (telepathy): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 (no longer want to live): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 (special/unusual person): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 (no future): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 (destined for importance): distress (1 not, 2 a bit, 3"
                " quite, 4 very), if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 (conspiracy): distress (1 not, 2 a bit, 3 quite, 4 very),"
                " if frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "distress1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 (sad): distress (1 not, 2 a bit, 3 quite, 4 very), if"
                " frequency > 1"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("cage", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q4, E (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q3, G (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q2, A (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Q1, C (Y, N)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("bprse", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, suspiciousness (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, grandiosity (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, elevated mood (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, hostility (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, guilt (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, suicidality (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, depression (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q24",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q24, mannerisms and posturing (1-7, higher worse, or 0 for"
                " not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q23",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q23, motor hyperactivity (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q22",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q22, distractibility (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21, excitement (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20, uncooperativeness (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, anxiety (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19, tension (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18, motor retardation (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17, emotional withdrawal (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16, blunted affect (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15, conceptual disorganisation (1-7, higher worse, or 0 for"
                " not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14, disorientation (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13, self-neglect (1-7, higher worse, or 0 for not assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, bizarre behaviour (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, unusual thought content (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, hallucinations (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, somatic concern (1-7, higher worse, or 0 for not"
                " assessed)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("bprs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9, depressive mood (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8, grandiosity (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7, mannerisms/posturing (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6, tension (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, guilt (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4, conceptual disorganisation (1-7, higher worse, 0 for"
                " unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3, emotional withdrawal (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20, global improvement (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2, anxiety (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19, severity of illness (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18, disorientation (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17, excitement (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16, blunted affect (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15, unusual thought content (1-7, higher worse, 0 for unable"
                " to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14, uncooperativeness (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13, motor retardation (1-7, higher worse, 0 for unable to"
                " rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, hallucinatory behaviour (1-7, higher worse, 0 for unable"
                " to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, suspiciousness (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10, hostility (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1, somatic concern (1-7, higher worse, 0 for unable to rate)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("bmi", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mass_kg",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="mass (kg)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "height_m",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="height (m)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comment",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comment",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("blobs", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "theblob",
            existing_type=sa.LargeBinary().with_variant(
                mysql.LONGBLOB, "mysql"
            ),
            comment=None,
            existing_comment=(
                "The BLOB itself, a binary object containing arbitrary"
                " information (such as a picture)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tablepk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Client-perspective primary key (id field) of the row"
                " referring to this BLOB"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "tablename",
            existing_type=sa.String(length=128),
            comment=None,
            existing_comment="Name of the table referring to this BLOB",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "mimetype",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="MIME type of the BLOB",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "image_rotation_deg_cw",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "For images: rotation to be applied, clockwise, in degrees"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "BLOB (binary large object) primary key on the source tablet"
                " device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "filename",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Filename of the BLOB on the source tablet device (on the"
                " source device, BLOBs are stored in files, not in the"
                " database)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fieldname",
            existing_type=sa.String(length=128),
            comment=None,
            existing_comment=(
                "Field name of the field referring to this BLOB by ID"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("bdi", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q9 [BDI-I: suicidal wishes; BDI-IA: suicidal ideas; BDI-II:"
                " suicidal thoughts or wishes] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q8 [BDI-I: self-accusation; BDI-IA: self-accusations; BDI-II:"
                " self-criticalness] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q7 [BDI-I: self-dislike; BDI-IA: self-dislike; BDI-II:"
                " self-dislike] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q6 [BDI-I: sense of punishment; BDI-IA: punishment; BDI-II:"
                " punishment feelings] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5 [BDI-I: guilt feelings; BDI-IA: guilt; BDI-II: guilty"
                " feelings] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q4 [BDI-I: lack of satisfaction; BDI-IA:"
                " self-dissatisfaction; BDI-II: loss of pleasure] (0-3, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q3 [BDI-I: sense of failure; BDI-IA: sense of failure;"
                " BDI-II: past failure] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q21",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q21 [BDI-I: loss of libido; BDI-IA: loss of libido; BDI-II:"
                " loss of interest in sex] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q20 [BDI-I: somatic preoccupation; BDI-IA: somatic"
                " preoccupation; BDI-II: tiredness or fatigue] (0-3, higher"
                " worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q2 [BDI-I: pessimism; BDI-IA: pessimism; BDI-II: pessimism]"
                " (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q19 [BDI-I: weight loss; BDI-IA: weight loss; BDI-II:"
                " concentration difficulty] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q18 [BDI-I: loss of appetite; BDI-IA: loss of appetite;"
                " BDI-II: changes in appetite] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q17 [BDI-I: fatigability; BDI-IA: fatigability; BDI-II:"
                " irritability] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q16 [BDI-I: sleep disturbance; BDI-IA: insomnia; BDI-II:"
                " changes in sleeping pattern] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q15 [BDI-I: work inhibition; BDI-IA: work difficulty; BDI-II:"
                " loss of energy] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q14 [BDI-I: distortion of body image; BDI-IA: body image"
                " change; BDI-II: worthlessness] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q13 [BDI-I: indecisiveness; BDI-IA: indecisiveness; BDI-II:"
                " indecisiveness] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12 [BDI-I: social withdrawal; BDI-IA: social withdrawal;"
                " BDI-II: loss of interest] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11 [BDI-I: irritability; BDI-IA: irritability; BDI-II:"
                " agitation] (0-3, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q10 [BDI-I: crying; BDI-IA: crying; BDI-II: crying] (0-3,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q1 [BDI-I: mood; BDI-IA: sadness; BDI-II: sadness] (0-3,"
                " higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bdi_scale",
            existing_type=sa.String(length=10),
            comment=None,
            existing_comment="Which BDI scale (BDI-I, BDI-IA, BDI-II)?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("badls", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "respondent_relationship",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(RESPONDENT) Respondent's relationship to patient"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "respondent_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(RESPONDENT) Respondent's name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q9, toilet/commode ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q8, bath/shower ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q7, teeth ('a' best [0] to 'd' worst [3]; 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q6, hygiene ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q5, dressing ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q4, drinking ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q3, drink ('a' best [0] to 'd' worst [3]; 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q20",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q20, transport ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q2, eating ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q19",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q19, games/hobbies ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q18",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q18, finances ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q17",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q17, shopping ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q16",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q16, hosuework/gardening ('a' best [0] to 'd' worst [3];"
                " 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q15",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q15, telephone ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q14",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q14, communication ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q13",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q13, orientation: space ('a' best [0] to 'd' worst [3];"
                " 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q12, orientation: time ('a' best [0] to 'd' worst [3];"
                " 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q11, mobility ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q10, transfers ('a' best [0] to 'd' worst [3]; 'e'=N/A"
                " [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Q1, food ('a' best [0] to 'd' worst [3]; 'e'=N/A [scored 0])"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("audit_c", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, how often six drinks (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, drinks per day (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, how often drink (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("audit", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, injuries (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, unable to remember (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, guilt (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, eye opener (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q5, unable to do what was expected (0-4, higher worse)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, unable to stop (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, how often six drinks (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, drinks per day (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, others concerned (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, how often drink (0-4, higher worse)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("apeqpt", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q_datetime",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Date/time the assessment tool was completed",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3_choice",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Preference offered (0 no, 1 yes, 2 N/A)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_satisfaction",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Service experience",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2_choice",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Treatment preference (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_satisfaction",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Patient satisfaction (0 not at all satisfied - 4 completely"
                " satisfied)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1_choice",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Enough information was provided (0 no, 1 yes)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("aims", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "q9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q9, incapacitation (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q8, global (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q7, trunk (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q6, lower_limbs (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q5, upper_limbs (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q4, tongue (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q3, jaw (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q2, lips (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q12, usually_wears_dentures (not scored) (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Q11, problems_teeth_dentures (not scored) (0 no, 1 yes)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q10, awareness (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "q1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Q1, facial_expression (0 none - 4 severe)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("ace3", schema=None) as batch_op:
        batch_op.alter_column(
            "when_last_modified",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(STANDARD) Date/time this row was last modified on the source"
                " tablet device (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_firstexit",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time of the first exit from this task (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "when_created",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(TASK) Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "vsp_identify_letter4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, identify letter 4/4, T (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_identify_letter3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, identify letter 3/4, A (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_identify_letter2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, identify letter 2/4, M (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_identify_letter1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, identify letter 1/4, K (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_draw_clock",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, draw clock (0-5)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, count dots 4/4, 9 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, count dots 3/4, 7 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, count dots 2/4, 10 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_count_dots1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, count dots 1/4, 8 dots (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_copy_infinity",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, copy infinity (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "vsp_copy_cube",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Visuospatial, copy cube (0-2)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "picture2_rotation",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Photo 2/2 rotation (degrees clockwise)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "picture2_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Photo 2/2 PNG BLOB ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "picture1_rotation",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Photo 1/2 rotation (degrees clockwise)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "picture1_blobid",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Photo 1/2 PNG BLOB ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Foreign key to patient.id (for this device/era)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "occupation",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Occupation",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 3/3 (scored), county (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 3/3 (scored), town (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 3/3 (scored), street_2 (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 3/3 (scored), street_1 (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 3/3 (scored), number (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 3/3 (scored), surname (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial3_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 3/3 (scored), forename (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 2/3 (not scored), county"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 2/3 (not scored), town (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 2/3 (not scored), street_2"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 2/3 (not scored), street_1"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 2/3 (not scored), number"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 2/3 (not scored), surname"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial2_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 2/3 (not scored), forename"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 1/3 (not scored), county"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 1/3 (not scored), town (0"
                " or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 1/3 (not scored), street_2"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 1/3 (not scored), street_1"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 1/3 (not scored), number"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 1/3 (not scored), surname"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_repeat_address_trial1_1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, address registration trial 1/3 (not scored), forename"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice5",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Memory, recognize address 5/5, CHOICE (if applicable)"
                " (county) (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice4",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Memory, recognize address 4/5, CHOICE (if applicable) (town)"
                " (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice3",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Memory, recognize address 3/5, CHOICE (if applicable)"
                " (street) (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice2",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Memory, recognize address 2/5, CHOICE (if applicable)"
                " (number) (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address_choice1",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment=(
                "Memory, recognize address 1/5, CHOICE (if applicable) (name)"
                " (A/B/C)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, recognize address 5/5 (if applicable) (county) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, recognize address 4/5 (if applicable) (town) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, recognize address 3/5 (if applicable) (street) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, recognize address 2/5 (if applicable) (number) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recognize_address1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, recognize address 1/5 (if applicable) (name) (0-1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_word3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall word, 3/3, ball (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_word2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall word, 2/3, key (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_word1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall word, 1/3, lemon (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall address 7/7, county (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall address 6/7, town (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall address 5/7, street_2 (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall address 4/7, street_1 (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall address 3/7, number (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall address 2/7, surname (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_recall_address1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, recall address 1/7, forename (0-1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, famous people, 4/4, JFK (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Memory, famous people, 3/4, USA president (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, famous people, 2/4, woman PM (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "mem_famous1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Memory, famous people, 1/4, current PM (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_write_sentences_point2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, write sentences, 2/2, grammar/spelling (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_write_sentences_point1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, write sentences, 1/2, two sentences on same topic"
                " (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, repeat word, 4/4, statistician (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, repeat word, 3/4, unintelligible (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, repeat word, 2/4, eccentricity (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_word1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, repeat word, 1/4, caterpillar (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_sentence2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, repeat sentence, 2/2, stitch_time (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_repeat_sentence1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, repeat sentence, 1/2, glitters_gold (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_read_words_aloud",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, read five irregular words (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture9",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, name picture, 9/12, barrel/keg/tub (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture8",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, name picture, 8/12, rhinoceros (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture7",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, name picture, 7/12, harp (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture6",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, name picture, 6/12, camel/dromedary (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, name picture, 5/12, anchor (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, name picture, 4/12, penguin (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, name picture, 3/12, kangaroo/wallaby (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, name picture, 2/12, book (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture12",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, name picture, 12/12, accordion/piano"
                " accordion/squeeze box (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture11",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, name picture, 11/12, alligator/crocodile (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture10",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, name picture, 10/12, crown (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_name_picture1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, name picture, 1/12, spoon (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, identify concept, 4/4, nautical (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, identify concept, 3/4, Antarctic (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, identify concept, 2/4, marsupial (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_identify_concept1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Language, identify concept, 1/4, monarchy (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_follow_command_practice",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, command, practice trial (not scored)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_follow_command3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, command 3/3 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_follow_command2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, command 2/3 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "lang_follow_command1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Language, command 1/3 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(TASK) Primary key (task ID) on the tablet device"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "handedness",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Handedness (L or R)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fluency_letters_score",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Fluency, words beginning with P, score 0-7",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "fluency_animals_score",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Fluency, animals, score 0-7",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_finish",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from the task because it was"
                " finished (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "firstexit_is_abort",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(TASK) Was the first exit from this task because it was"
                " aborted (1)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "editing_time_s",
            existing_type=sa.Float(),
            comment=None,
            existing_comment="(TASK) Time spent editing (s)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "comments",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Clinician's comments",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_specialty",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's specialty (e.g. Liaison Psychiatry)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_service",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's service (e.g. Liaison Psychiatry"
                " Service)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_professional_registration",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's professional registration (e.g. GMC#"
                " 12345)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_post",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's post (e.g. Consultant)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(CLINICIAN) Clinician's name (e.g. Dr X)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "clinician_contact_details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(CLINICIAN) Clinician's contact details (e.g. bleep,"
                " extension)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, time, 5/5, season (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, time, 4/5, year (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, time, 3/5, month (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, time, 2/5, date (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_time1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, time, 1/5, day (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, serial sevens, 5/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, serial sevens, 4/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, serial sevens, 3/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, serial sevens, 2/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_serial7_subtraction1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, serial sevens, 1/5 (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_repeat_word3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, repeat word, 3/3, ball (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_repeat_word2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, repeat word, 2/3, key (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_repeat_word1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, repeat word, 1/3, lemon (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place5",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, place, 5/5, country (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place4",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, place, 4/5, county (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place3",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, place, 3/5, town (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place2",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Attention, place, 2/5, street/hospital (0 or 1)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_place1",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Attention, place, 1/5, house number/floor (0 or 1)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "attn_num_registration_trials",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Attention, repetition, number of trials (not scored)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "age_at_leaving_full_time_education",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Age at leaving full time education",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was removed, i.e. made not"
                " current (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_removed_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that removed this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_exact",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time this row was added (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "(SERVER) Date/time of the upload batch that added this row"
                " (DATETIME in UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_successor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of successor record  (after modification) or NULL"
                " (whilst live, or after deletion)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that removed this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_removal_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Removal pending?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_preserving_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that preserved this row",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_predecessor_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) PK of predecessor record, prior to modification"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) Primary key (on the server)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "_move_off_tablet",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER/TABLET) Record-specific preservation pending?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erasing_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of user that erased this row manually"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="(SERVER) Date/time of manual erasure (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_manually_erased",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Record manually erased (content destroyed)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(SERVER) ID of group to which this record belongs"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_forcibly_preserved",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(SERVER) Forcibly preserved by superuser (rather than"
                " normally preserved by tablet)?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment=(
                "(SERVER) 'NOW', or when this row was preserved and removed"
                " from the source device (UTC ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Is the row current (1) or not (0)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment=(
                "(SERVER) CamCOPS version number of the uploading device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "_addition_pending",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(SERVER) Addition pending?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "_adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(SERVER) ID of user that added this row",
            existing_nullable=True,
        )

    with op.batch_alter_table("_task_index", schema=None) as batch_op:
        batch_op.alter_column(
            "when_created_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time this task instance was created (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_created_iso",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "Date/time this task instance was created (ISO 8601)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "when_added_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time this task index was uploaded (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "task_table_name",
            existing_type=sa.String(length=128),
            comment=None,
            existing_comment="Table name of the task's base table",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Server primary key of the task",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_is_complete",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Is the task complete (as judged by the server when the index"
                " entry was created)?"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Server primary key of the patient (if applicable)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "indexed_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="When this index entry was created",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "index_entry_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Arbitrary primary key of this index entry",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="ID of group to which this task belongs",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment="Era (_era) field of the source record",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="ID of the source tablet device",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "adding_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="ID of user that added this task",
            existing_nullable=True,
        )

    with op.batch_alter_table("_task_filters", schema=None) as batch_op:
        batch_op.alter_column(
            "user_ids",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Task filter: adding (uploading) user ID(s), as CSV"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "text_contents",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Task filter: filter text fields",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tasks_with_patient_only",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Task filter: restrict to tasks with a patient (non-anonymous"
                " tasks) only?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "tasks_offering_trackers_only",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Task filter: restrict to tasks offering trackers only?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_types",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Task filter: task type(s), as CSV list of table names"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "surname",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Task filter: surname",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_datetime_iso8601",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Task filter: start date/time (UTC as ISO8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sex",
            existing_type=sa.String(length=1),
            comment=None,
            existing_comment="Task filter: sex",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "idnum_criteria",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "ID filters as JSON; the ID number definitions are joined"
                " with OR"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Task filter ID (arbitrary integer)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "group_ids",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Task filter: group ID(s), as CSV",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "forename",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Task filter: forename",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "end_datetime_iso8601",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Task filter: end date/time (UTC as ISO8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "dob",
            existing_type=sa.DATE(),
            comment=None,
            existing_comment="Task filter: DOB",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "device_ids",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Task filter: source device ID(s), as CSV",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "complete_only",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Task filter: task complete?",
            existing_nullable=True,
        )

    with op.batch_alter_table("_special_notes", schema=None) as batch_op:
        batch_op.alter_column(
            "user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="User that entered this note",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Client-side ID of the task, or patient, concerned (part"
                " of FK)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "note_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "note_at",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment="Date/time of note entry (ISO 8601)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "note",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Special note, added manually",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hidden",
            existing_type=sa.Boolean(),
            existing_comment="Manually hidden (effectively: deleted)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "era",
            existing_type=sa.String(length=32),
            comment=None,
            existing_comment="Era (part of FK)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Source tablet device (part of FK)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "basetable",
            existing_type=sa.String(length=128),
            comment=None,
            existing_comment="Base table of task concerned (part of FK)",
            existing_nullable=True,
        )

    with op.batch_alter_table("_server_settings", schema=None) as batch_op:
        batch_op.alter_column(
            "last_dummy_login_failure_clearance_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "Date/time (in UTC) when login failure records were cleared"
                " for nonexistent users (security feature)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "PK (arbitrary integer but only a value of 1 is ever used)"
            ),
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "database_title",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Database title",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "_security_webviewer_sessions", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="User ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "token",
            existing_type=sa.String(length=88),
            comment=None,
            existing_comment="Token (base 64 encoded random number)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "task_filter_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Task filter ID",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "number_to_view",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Number of records to view",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_activity_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time of last activity (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ip_address",
            existing_type=sa.String(length=45),
            comment=None,
            existing_comment="IP address of user",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Session ID (internal number for insertion speed)"
            ),
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )

    with op.batch_alter_table("_security_users", schema=None) as batch_op:
        batch_op.alter_column(
            "when_agreed_terms_of_use",
            existing_type=PendulumDateTimeAsIsoTextColType(length=32),
            comment=None,
            existing_comment=(
                "Date/time this user acknowledged the Terms and Conditions of"
                " Use (ISO 8601)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=191),
            comment=None,
            existing_comment="User name",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "upload_group_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "ID of the group to which this user uploads at present"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "superuser",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Superuser?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "must_change_password",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Must change password at next webview login",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_password_change_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "Date/time this user last changed their password (UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_login_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time this user last logged in (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="User ID",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "hashedpw",
            existing_type=sa.String(length=60),
            comment=None,
            existing_comment="Password hash",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "fullname",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="User's full name",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="User's e-mail address",
            existing_nullable=True,
        )

    with op.batch_alter_table("_security_user_group", schema=None) as batch_op:
        batch_op.alter_column(
            "view_all_patients_when_unfiltered",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "When no record filters are applied, can the user see all"
                " records? (If not, then none are shown.)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_use_webviewer",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "May the user use the web front end to view CamCOPS data?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_upload",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="May the user upload data from a tablet device?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_run_reports",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "May the user run reports via the web interface? (Overrides"
                " other view restrictions.)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_register_devices",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="May the user register tablet devices?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_dump_data",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "May the user run database data dumps via the web interface?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "may_add_notes",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="May the user add special notes to tasks?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "groupadmin",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Is the user a privileged administrator for this group?"
            ),
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "_security_login_failures", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=191),
            comment=None,
            existing_comment=(
                "User name (which may be a non-existent user, to prevent"
                " subtle username discovery by careful timing)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "login_failure_at",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Login failure occurred at (UTC)",
            existing_nullable=False,
        )

    with op.batch_alter_table("_security_groups", schema=None) as batch_op:
        batch_op.alter_column(
            "upload_policy",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="Upload policy for the group, as a string",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "name",
            existing_type=sa.Unicode(length=191),
            comment=None,
            existing_comment="Group name",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Group ID",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "finalize_policy",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="Finalize policy for the group, as a string",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Description of the group",
            existing_nullable=True,
        )

    with op.batch_alter_table("_security_devices", schema=None) as batch_op:
        batch_op.alter_column(
            "when_registered_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time when the device was registered (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "uploading_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "ID of user in the process of uploading right now"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "registered_by_user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="ID of user that registered the device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "ongoing_upload_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "Date/time when the device's ongoing upload batch started"
                " (UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "name",
            existing_type=sa.String(length=191),
            comment=None,
            existing_comment=(
                "Short cryptic unique name of the source tablet device"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "last_upload_batch_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment=(
                "Date/time when the device's last upload batch started (UTC)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="ID of the source tablet device",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "friendly_name",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Friendly name of the device",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "currently_preserving",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Preservation currently in progress",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "camcops_version",
            existing_type=SemanticVersionColType(length=147),
            comment=None,
            existing_comment="CamCOPS version number on the tablet device",
            existing_nullable=True,
        )

    with op.batch_alter_table("_security_audit", schema=None) as batch_op:
        batch_op.alter_column(
            "when_access_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time of access (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "user_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="ID of user, where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "table_name",
            existing_type=sa.String(length=128),
            comment=None,
            existing_comment="Table involved, where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "source",
            existing_type=sa.String(length=20),
            comment=None,
            existing_comment="Source (e.g. tablet, webviewer)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "server_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Server PK (table._pk), where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "remote_addr",
            existing_type=sa.String(length=45),
            comment=None,
            existing_comment="IP address of the remote computer",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "patient_server_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Server PK of the patient (patient._pk) concerned, or NULL if"
                " not applicable"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Device ID, where applicable",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "details",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Details of the access",
            existing_nullable=True,
        )

    with op.batch_alter_table(
        "_security_account_lockouts", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=191),
            comment=None,
            existing_comment=(
                "User name (which may be a non-existent user, to prevent"
                " subtle username discovery by careful timing)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "locked_until",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Account is locked until (UTC)",
            existing_nullable=False,
        )

    with op.batch_alter_table("_idnum_index", schema=None) as batch_op:
        batch_op.alter_column(
            "which_idnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Which of the server's ID numbers is this?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "patient_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Server primary key of the Patient",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "indexed_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="When this index entry was created",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "idnum_value",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="The value of the ID number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "idnum_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Server primary key of the PatientIdNum (and of the"
                " PatientIdNumIndexEntry)"
            ),
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )

    with op.batch_alter_table("_idnum_definitions", schema=None) as batch_op:
        batch_op.alter_column(
            "which_idnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Which of the server's ID numbers is this?",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "validation_method",
            existing_type=sa.String(length=50),
            comment=None,
            existing_comment="Optional validation method",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "short_description",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Short description of the ID number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_id_type",
            existing_type=sa.String(length=5),
            comment=None,
            existing_comment=(
                "HL7: Identifier Type code: 'a code corresponding to the type"
                " of identifier. In some cases, this code may be used as a"
                ' qualifier to the "Assigning Authority" component.\''
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_assigning_authority",
            existing_type=sa.String(length=20),
            comment=None,
            existing_comment=(
                "HL7: Assigning Authority for ID number (unique name of the"
                " system/organization/agency/department that creates the"
                " data)."
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Full description of the ID number",
            existing_nullable=True,
        )

    with op.batch_alter_table("_exported_tasks", schema=None) as batch_op:
        batch_op.alter_column(
            "task_server_pk",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Server PK of task in basetable (_pk field)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "success",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Task exported successfully?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "start_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Time export was started (UTC)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "recipient_id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="FK to _export_recipients.id",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "finish_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Time export was finished (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "failure_reasons",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Reasons for failure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cancelled_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Time export was cancelled at (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cancelled",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Export subsequently cancelled/invalidated (may trigger"
                " resend)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "basetable",
            existing_type=sa.String(length=128),
            comment=None,
            existing_comment="Base table of task concerned",
            existing_nullable=False,
        )

    with op.batch_alter_table(
        "_exported_task_hl7msg", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "success",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Message sent successfully and acknowledged by HL7 server"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sent_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Time message was sent at (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "reply_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Time message was replied to (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "reply",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Server's reply, if kept",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "message",
            existing_type=sa.UnicodeText().with_variant(
                mysql.LONGTEXT, "mysql"
            ),
            comment=None,
            existing_comment="Message body, if kept",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "failure_reason",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Reason for failure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "exported_task_id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="FK to _exported_tasks.id",
            existing_nullable=False,
        )

    with op.batch_alter_table(
        "_exported_task_filegroup", schema=None
    ) as batch_op:
        batch_op.alter_column(
            "script_stdout",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="stdout from the FILE_SCRIPT_AFTER_EXPORT script",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "script_stderr",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="stderr from the FILE_SCRIPT_AFTER_EXPORT script",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "script_retcode",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "Return code from the FILE_SCRIPT_AFTER_EXPORT script"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "script_called",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Was the FILE_SCRIPT_AFTER_EXPORT script called?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "filenames",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="List of filenames exported",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "exported_task_id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="FK to _exported_tasks.id",
            existing_nullable=False,
        )

    with op.batch_alter_table("_exported_task_email", schema=None) as batch_op:
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "exported_task_id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="FK to _exported_tasks.id",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "email_id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="FK to _emails.id",
            existing_nullable=True,
        )

    with op.batch_alter_table("_export_recipients", schema=None) as batch_op:
        batch_op.alter_column(
            "xml_field_comments",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Whether to include field comments in XML output",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "transmission_method",
            existing_type=sa.String(length=50),
            comment=None,
            existing_comment="Export transmission method (e.g. hl7, file)",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "task_format",
            existing_type=sa.String(length=50),
            comment=None,
            existing_comment=(
                "Format that task information should be sent in (e.g. PDF), if"
                " not predetermined by the transmission method"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "start_datetime_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Start date/time for tasks (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rio_uploading_user",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(FILE / RiO) RiO metadata: name of automatic upload user"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rio_idnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment=(
                "(FILE / RiO) RiO metadata: which ID number is the RiO ID?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "rio_document_type",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "(FILE / RiO) RiO metadata: document type for RiO"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "require_idnum_mandatory",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Must the primary ID number be mandatory in the relevant"
                " policy?"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "recipient_name",
            existing_type=sa.String(length=191),
            comment=None,
            existing_comment="Name of export recipient",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "push",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Push (support auto-export on upload)?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "primary_idnum",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Which ID number is used as the primary ID?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "include_anonymous",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Include anonymous tasks? Not applicable to some methods (e.g."
                " HL7)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="Export recipient ID (arbitrary primary key)",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "hl7_port",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(HL7) Destination port number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_ping_first",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(HL7) Ping via TCP/IP before sending HL7 messages?"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_network_timeout_ms",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(HL7) Network timeout (ms).",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_keep_reply",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(HL7) Keep copy of server's reply in database?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_keep_message",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(HL7) Keep copy of message in database? (May be large!)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_host",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="(HL7) Destination host name/IP address",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "hl7_debug_treat_diverted_as_sent",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(HL7 debugging option) Treat messages diverted to file as"
                " sent"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "hl7_debug_divert_to_file",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(HL7 debugging option) Divert messages to files?"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "group_ids",
            existing_type=sa.Text(),
            comment=None,
            existing_comment=(
                "Integer IDs of CamCOPS group to export data from (as CSV)"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "finalized_only",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Send only finalized tasks",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "file_script_after_export",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(FILE) Command/script to run after file export",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_patient_spec_if_anonymous",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment=(
                "(FILE) Patient part of filename specification for anonymous"
                " tasks"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_patient_spec",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="(FILE) Patient part of filename specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_overwrite_files",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(FILE) Overwrite existing files",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "file_make_directory",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(FILE) Make destination directory if it doesn't already exist"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "file_filename_spec",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="(FILE) Filename specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "file_export_rio_metadata",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(FILE) Export RiO metadata file along with main file?"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "end_datetime_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="End date/time for tasks (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_use_tls",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(EMAIL) Use explicit TLS connection?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "email_to",
            existing_type=sa.Text(),
            comment=None,
            existing_comment='(EMAIL) "To:" recipient(s), as a CSV list',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_subject",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="(EMAIL) Subject specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_sender",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment='(EMAIL) "Sender:" address(es)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_reply_to",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment='(EMAIL) "Reply-To:" address(es)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_port",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="(EMAIL) E-mail (SMTP) server port number",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_patient_spec_if_anonymous",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment=(
                "(EMAIL) Patient specification for anonymous tasks"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_patient",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="(EMAIL) Patient specification",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_keep_message",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(EMAIL) Keep entire message?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "email_host_username",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="(EMAIL) Username on e-mail server",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_host",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment=(
                "(EMAIL) E-mail (SMTP) server host name/IP address"
            ),
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_from",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment='(EMAIL) "From:" address(es)',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_cc",
            existing_type=sa.Text(),
            comment=None,
            existing_comment='(EMAIL) "CC:" recipient(s), as a CSV list',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_body_as_html",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(EMAIL) Is the body HTML, rather than plain text?"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "email_body",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="(EMAIL) Body contents",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "email_bcc",
            existing_type=sa.Text(),
            comment=None,
            existing_comment='(EMAIL) "BCC:" recipient(s), as a CSV list',
            existing_nullable=True,
        )
        batch_op.alter_column(
            "db_url",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="(DATABASE) SQLAlchemy database URL for export",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "db_patient_id_per_row",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(DATABASE) Add patient ID information per row?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_include_blobs",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(DATABASE) Include BLOBs?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_echo",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "(DATABASE) Echo SQL applied to destination database?"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "db_add_summaries",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="(DATABASE) Add summary information?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "current",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment=(
                "Is this the current record for this recipient? (If not, it's"
                " a historical record for audit purposes.)"
            ),
            existing_nullable=False,
        )
        batch_op.alter_column(
            "all_groups",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Export all groups? (If not, see group_ids.)",
            existing_nullable=False,
        )

    with op.batch_alter_table("_emails", schema=None) as batch_op:
        batch_op.alter_column(
            "username",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="Username on e-mail server",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "use_tls",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Use TLS?",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "to",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Email 'To:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "subject",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Email 'Subject:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sent_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time message was sent (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sent",
            existing_type=sa.Boolean(),
            comment=None,
            existing_comment="Sent?",
            existing_nullable=False,
        )
        batch_op.alter_column(
            "sending_failure_reason",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Reason for sending failure",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "sender",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Email 'Sender:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "reply_to",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Email 'Reply-To:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "port",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Port number on e-mail server",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "msg_string",
            existing_type=sa.UnicodeText().with_variant(
                mysql.LONGTEXT, "mysql"
            ),
            comment=None,
            existing_comment="Full encoded e-mail",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "id",
            existing_type=sa.BigInteger(),
            comment=None,
            existing_comment="Arbitrary primary key",
            existing_nullable=False,  # added by RNC
            autoincrement=True,
        )
        batch_op.alter_column(
            "host",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="Email server",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "from_addr",
            existing_type=sa.Unicode(length=255),
            comment=None,
            existing_comment="Email 'From:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "date",
            existing_type=sa.String(length=31),
            comment=None,
            existing_comment="Email date in RFC 2822 format",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "created_at_utc",
            existing_type=sa.DateTime(),
            comment=None,
            existing_comment="Date/time message was created (UTC)",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "content_type",
            existing_type=sa.String(length=255),
            comment=None,
            existing_comment="MIME type for e-mail body",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "charset",
            existing_type=sa.String(length=64),
            comment=None,
            existing_comment="Character set for e-mail body",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "cc",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Email 'Cc:' field",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "body",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Email body",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "bcc",
            existing_type=sa.Text(),
            comment=None,
            existing_comment="Email 'Bcc:' field",
            existing_nullable=True,
        )

    with op.batch_alter_table("_dirty_tables", schema=None) as batch_op:
        batch_op.alter_column(
            "tablename",
            existing_type=sa.String(length=128),
            comment=None,
            existing_comment="Table in the process of being preserved",
            existing_nullable=True,
        )
        batch_op.alter_column(
            "device_id",
            existing_type=sa.Integer(),
            comment=None,
            existing_comment="Source tablet device ID",
            existing_nullable=True,
        )

    # ### end Alembic commands ###
