'Read the given fields of the records in ``self`` from the database,
and store them in cache. Access errors are also stored in cache.
:param field_names: list of column names of model ``self``; all those
fields are guaranteed to be read
:param inherited_field_names: list of column names from parent
models; some of those fields may not be read'

@api.multi
def _read_from_database(self, field_names, inherited_field_names=[]):

    env = self.env
    (cr, user, context) = env.args
    param_ids = object()
    query = Query([('"%s"' % self._table)], [('"%s".id    IN    %%s' % self._table)], [param_ids])
    self._apply_ir_rules(query, 'read')
    order_str = self._generate_order_by(None, query)
    fields = map(self._fields.get, (field_names + inherited_field_names))
    fields_pre = [field for field in fields if (field.base_field.store and field.base_field.column_type) if (not (field.inherited and callable(field.base_field.translate)))]
    def qualify(field):
        col = field.name
        res = self._inherits_join_calc(self._table, field.name, query)
        if ((field.type == 'binary') and (context.get('bin_size') or context.get(('bin_size_' + col)))):
            res = ('pg_size_pretty(length(%s)::bigint)' % res)
        return ('%s    as    "%s"' % (res, col))
    qual_names = map(qualify, set((fields_pre + [self._fields['id']])))
    (from_clause, where_clause, params) = query.get_sql()
    query_str = ('    SELECT    %(qual_names)s    FROM    %(from_clause)s\n                                                                                                WHERE    %(where_clause)s    %(order_str)s\n                                                                                ' % {'qual_names': ','.join(qual_names), 'from_clause': from_clause, 'where_clause': where_clause, 'order_str': order_str})
    result = []
    param_pos = params.index(param_ids)
    for sub_ids in cr.split_for_in_conditions(self.ids):
        params[param_pos] = tuple(sub_ids)
        cr.execute(query_str, params)
        result.extend(cr.dictfetchall())
    ids = [vals['id'] for vals in result]
    fetched = self.browse(ids)
    if ids:
        if context.get('lang'):
            for field in fields_pre:
                if ((not field.inherited) and callable(field.translate)):
                    f = field.name
                    translate = field.get_trans_func(fetched)
                    for vals in result:
                        vals[f] = translate(vals['id'], vals[f])
        for vals in result:
            record = self.browse(vals['id'], self._prefetch)
            record._cache.update(record._convert_to_cache(vals, validate=False))
        for f in field_names:
            field = self._fields[f]
            if (not field.column_type):
                field.read(fetched)
    for f in field_names:
        field = self._fields[f]
        if field.deprecated:
            _logger.warning('Field    %s    is    deprecated:    %s', field, field.deprecated)
    missing = (self - fetched)
    if missing:
        extras = (fetched - self)
        if extras:
            raise AccessError(_('Database    fetch    misses    ids    ({})    and    has    extra    ids    ({}),    may    be    caused    by    a    type    incoherence    in    a    previous    request').format(',    '.join(map(repr, missing._ids)), ',    '.join(map(repr, extras._ids))))
        forbidden = missing.exists()
        if forbidden:
            exc = AccessError((_('The    requested    operation    cannot    be    completed    due    to    security    restrictions.    Please    contact    your    system    administrator.\n\n(Document    type:    %s,    Operation:    %s)') % (self._name, 'read')))
            forbidden._cache.update(FailedValue(exc))
