'Method to help with migration to objects.
Converts a database entity to a formal object.'

@staticmethod
def _from_db_object(context, instance, db_inst, expected_attrs=None):

    instance._context = context
    if (expected_attrs is None):
        expected_attrs = []
    for field in instance.fields:
        if (field in INSTANCE_OPTIONAL_ATTRS):
            continue
        elif (field == 'deleted'):
            instance.deleted = (db_inst['deleted'] == db_inst['id'])
        elif (field == 'cleaned'):
            instance.cleaned = (db_inst['cleaned'] == 1)
        else:
            instance[field] = db_inst[field]
    if hasattr(db_inst, '__dict__'):
        have_extra = (('extra' in db_inst.__dict__) and db_inst['extra'])
    else:
        have_extra = (('extra' in db_inst) and db_inst['extra'])
    if ('metadata' in expected_attrs):
        instance['metadata'] = utils.instance_meta(db_inst)
    if ('system_metadata' in expected_attrs):
        instance['system_metadata'] = utils.instance_sys_meta(db_inst)
    if ('fault' in expected_attrs):
        instance['fault'] = objects.InstanceFault.get_latest_for_instance(context, instance.uuid)
    if ('numa_topology' in expected_attrs):
        if have_extra:
            instance._load_numa_topology(db_inst['extra'].get('numa_topology'))
        else:
            instance.numa_topology = None
    if ('pci_requests' in expected_attrs):
        if have_extra:
            instance._load_pci_requests(db_inst['extra'].get('pci_requests'))
        else:
            instance.pci_requests = None
    if ('device_metadata' in expected_attrs):
        if have_extra:
            instance._load_device_metadata(db_inst['extra'].get('device_metadata'))
        else:
            instance.device_metadata = None
    if ('vcpu_model' in expected_attrs):
        if have_extra:
            instance._load_vcpu_model(db_inst['extra'].get('vcpu_model'))
        else:
            instance.vcpu_model = None
    if ('ec2_ids' in expected_attrs):
        instance._load_ec2_ids()
    if ('migration_context' in expected_attrs):
        if have_extra:
            instance._load_migration_context(db_inst['extra'].get('migration_context'))
        else:
            instance.migration_context = None
    if ('keypairs' in expected_attrs):
        if have_extra:
            instance._load_keypairs(db_inst['extra'].get('keypairs'))
    if ('info_cache' in expected_attrs):
        if (db_inst.get('info_cache') is None):
            instance.info_cache = None
        elif (not instance.obj_attr_is_set('info_cache')):
            instance.info_cache = objects.InstanceInfoCache(context)
        if (instance.info_cache is not None):
            instance.info_cache._from_db_object(context, instance.info_cache, db_inst['info_cache'])
    if any([(x in expected_attrs) for x in ('flavor', 'old_flavor', 'new_flavor')]):
        if (have_extra and db_inst['extra'].get('flavor')):
            instance._flavor_from_db(db_inst['extra']['flavor'])
    if ('pci_devices' in expected_attrs):
        pci_devices = base.obj_make_list(context, objects.PciDeviceList(context), objects.PciDevice, db_inst['pci_devices'])
        instance['pci_devices'] = pci_devices
    if ('security_groups' in expected_attrs):
        sec_groups = base.obj_make_list(context, objects.SecurityGroupList(context), objects.SecurityGroup, db_inst.get('security_groups', []))
        instance['security_groups'] = sec_groups
    if ('tags' in expected_attrs):
        tags = base.obj_make_list(context, objects.TagList(context), objects.Tag, db_inst['tags'])
        instance['tags'] = tags
    if ('services' in expected_attrs):
        services = base.obj_make_list(context, objects.ServiceList(context), objects.Service, db_inst['services'])
        instance['services'] = services
    instance.obj_reset_changes()
    return instance
