Exemplo n.º 1
0
def rebuild_table(table, delete_missing=False):
    from virtuoso.alchemy import AddForeignKey, DropForeignKey
    print "rebuilding", table
    session = get_session_maker()()
    incoming = set(get_incoming_fks(table))
    outgoing = set(table.foreign_keys)
    all_fkeys = incoming | outgoing
    self_ref = incoming & outgoing
    try:
        for fk in all_fkeys:
            if not delete_rows_with_missing_fkey(fk, delete_missing):
                print "There are missing keys, will not rebuild " + table.name
                return
    except Exception as e:
        traceback.print_exc()
        print "Could not delete missing keys"
        raise e
    # Booleans with NULL values
    for col in table.c:
        if isinstance(col.type, Boolean):
            session.execute(
                table.update().where(col == None).values(**{col.name: 0}))
    # Drop all keys
    for fk in all_fkeys:
        try:
            session.execute(DropForeignKey(fk))
        except Exception as e:
            print "Could not drop fkey %s, maybe does not exist." % (
                fk_as_str(fk), )
            print e
    clone = clone_table(table, table.name + "_temp", False, False)
    clone.create(session.bind)
    column_names = [c.name for c in table.columns]
    sel = select([getattr(table.c, cname) for cname in column_names])
    with transaction.manager:
        session.execute(clone.insert().from_select(column_names, sel))
        mark_changed(session)
    session.execute(DropTable(table))
    # Should we create it without outgoing first?
    table.create(session.bind)
    # self ref will make the insert fail.
    for fk in self_ref:
        try:
            session.execute(DropForeignKey(fk))
        except Exception as e:
            print "Could not drop fkey %s, maybe does not exist." % (
                fk_as_str(fk), )
            print e
    sel = select([getattr(clone.c, cname) for cname in column_names])
    with transaction.manager:
        session.execute(table.insert().from_select(column_names, sel))
        mark_changed(session)
    session.execute(DropTable(clone))
    if delete_missing:
        # Delete a second time, in case.
        for fk in outgoing:
            assert delete_rows_with_missing_fkey(fk, True), "OUCH"
    for fk in incoming:  # includes self_ref
        session.execute(AddForeignKey(fk))
Exemplo n.º 2
0
def rebuild_fkey(session, fk, delete_missing=False):
    from virtuoso.alchemy import AddForeignKey, DropForeignKey
    if not delete_rows_with_missing_fkey(fk, delete_missing):
        print "There are missing keys, will not reset ", fk_as_str(fk)
        return
    try:
        session.execute(DropForeignKey(fk))
    except Exception as e:
        print "Could not drop fkey %s, maybe does not exist." % (fk_as_str(fk),)
        print e
    try:
        session.execute(AddForeignKey(fk))
    except Exception as e:
        print e
        try:
            session.execute(AddForeignKey(fk))
        except Exception:
            rebuild_table(fk.parent.table, delete_missing)
            return False
    return True