def add_primary_relationship(parent, childrel, child, parentrel, parentcol):
    """
    When a parent-child relationship is defined as one-to-many,
    :func:`add_primary_relationship` lets the parent refer to one child as the
    primary, by creating a secondary table to hold the reference. Under
    PostgreSQL, a trigger is added as well to ensure foreign key integrity.

    A SQLAlchemy relationship named ``parent.childrel`` is added that makes
    usage seamless within SQLAlchemy.

    The secondary table is named after the parent and child tables, with
    ``_primary`` appended, in the form ``parent_child_primary``. This table can
    be found in the metadata in the ``parent.metadata.tables`` dictionary.

    Multi-column primary keys on either parent or child are unsupported at
    this time.

    :param parent: The parent model (on which this relationship will be added)
    :param childrel: The name of the relationship to the child that will be
        added
    :param child: The child model
    :param str parentrel: Name of the existing relationship on the child model
        that refers back to the parent model
    :param str parentcol: Name of the existing table column on the child model
        that refers back to the parent model
    :return: None
    """

    parent_table_name = parent.__tablename__
    child_table_name = child.__tablename__
    primary_table_name = parent_table_name + '_' + child_table_name + '_primary'
    parent_id_columns = [c.name for c in inspect(parent).primary_key]
    child_id_columns = [c.name for c in inspect(child).primary_key]

    primary_table_columns = (
        [Column(
            parent_table_name + '_' + name,
            None,
            ForeignKey(parent_table_name + '.' + name, ondelete='CASCADE'),
            primary_key=True,
            nullable=False) for name in parent_id_columns]
        + [Column(
            child_table_name + '_' + name,
            None,
            ForeignKey(child_table_name + '.' + name, ondelete='CASCADE'),
            nullable=False) for name in child_id_columns]
        + list(make_timestamp_columns())
    )

    primary_table = Table(primary_table_name, parent.metadata, *primary_table_columns)
    rel = relationship(child, uselist=False, secondary=primary_table)
    setattr(parent, childrel, rel)

    @event.listens_for(rel, 'set')
    def _validate_child(target, value, oldvalue, initiator):
        if value and getattr(value, parentrel) != target:
            raise ValueError("The target is not affiliated with this parent")

    # XXX: To support multi-column primary keys, update this SQL function
    event.listen(primary_table, 'after_create',
        DDL('''
            CREATE FUNCTION %(function)s() RETURNS TRIGGER AS $$
            DECLARE
                target RECORD;
            BEGIN
                IF (NEW.%(rhs)s IS NOT NULL) THEN
                    SELECT %(parentcol)s INTO target FROM %(child_table_name)s WHERE %(child_id_column)s = NEW.%(rhs)s;
                    IF (target.%(parentcol)s != NEW.%(lhs)s) THEN
                        RAISE foreign_key_violation USING MESSAGE = 'The target is not affiliated with this parent';
                    END IF;
                END IF;
                RETURN NEW;
            END;
            $$ LANGUAGE plpgsql;
            CREATE TRIGGER %(trigger)s BEFORE INSERT OR UPDATE
            ON %(table)s
            FOR EACH ROW EXECUTE PROCEDURE %(function)s();
            ''',
            context={
                'table': primary_table_name,
                'function': '%s_validate' % primary_table_name,
                'trigger': '%s_trigger' % primary_table_name,
                'parentcol': parentcol,
                'child_table_name': child_table_name,
                'child_id_column': child_id_columns[0],
                'lhs': '%s_%s' % (parent_table_name, parent_id_columns[0]),
                'rhs': '%s_%s' % (child_table_name, child_id_columns[0]),
            }
        ).execute_if(dialect='postgresql')
    )

    event.listen(primary_table, 'before_drop',
        DDL('''
            DROP TRIGGER %(trigger)s ON %(table)s;
            DROP FUNCTION %(function)s();
            ''',
            context={
                'table': primary_table_name,
                'trigger': '%s_trigger' % primary_table_name,
                'function': '%s_validate' % primary_table_name,
            }
        ).execute_if(dialect='postgresql')
    )