'Reflect the model and initialize the database schema of ``self``:
- create the corresponding table in database,
- add the parent columns in database,
- add the \'_log_access\' columns if required,
- report on database columns no more existing in ``self._fields``,
- remove no more existing not null constraints,
- alter existing database columns to match ``self._fields``,
- create database tables to match ``self._fields``,
- add database indices to match ``self._fields``,
- save in self._foreign_keys a list a foreign keys to create (see
_auto_end).
Note: you should not override this method. Instead, you can modify the
model\'s database schema by overriding method :meth:`~.init`, which is
called right after this one.'

@api.model_cr_context
def _auto_init(self):

    assert ('todo' in self._context), 'Context    not    passed    correctly    to    method    _auto_init().'
    type(self)._foreign_keys = set()
    raise_on_invalid_object_name(self._name)
    self = self.with_context(prefetch_fields=False)
    cr = self._cr
    parent_store_compute = False
    stored_fields = []
    todo_end = self._context['todo']
    update_custom_fields = self._context.get('update_custom_fields', False)
    self._field_create()
    create = (not self._table_exist())
    if self._auto:
        if create:
            self._create_table()
            has_rows = False
        else:
            cr.execute(('SELECT    1    FROM    "%s"    LIMIT    1' % self._table))
            has_rows = cr.rowcount
        cr.commit()
        if self._parent_store:
            if (not self._parent_columns_exist()):
                self._create_parent_columns()
                parent_store_compute = True
        self._check_removed_columns(log=False)
        column_data = self._select_column_data()
        for (name, field) in self._fields.iteritems():
            if (name == 'id'):
                continue
            if (not field.store):
                continue
            if (field.manual and (not update_custom_fields)):
                continue
            if (not field.column_type):
                if (field.check_schema(self) and field.compute):
                    stored_fields.append(field)
            else:
                res = column_data.get(name)
                if ((not res) and hasattr(field, 'oldname')):
                    res = column_data.get(field.oldname)
                    if res:
                        cr.execute(('ALTER    TABLE    "%s"    RENAME    "%s"    TO    "%s"' % (self._table, field.oldname, name)))
                        res['attname'] = name
                        _schema.debug("Table    '%s':    renamed    column    '%s'    to    '%s'", self._table, field.oldname, name)
                if res:
                    f_pg_type = res['typname']
                    f_pg_size = res['size']
                    f_pg_notnull = res['attnotnull']
                    column_type = field.column_type
                    if column_type:
                        converted = False
                        casts = [('text', 'char', column_type[1], ('::' + column_type[1])), ('varchar', 'text', 'TEXT', ''), ('int4', 'float', column_type[1], ('::' + column_type[1])), ('date', 'datetime', 'TIMESTAMP', '::TIMESTAMP'), ('timestamp', 'date', 'date', '::date'), ('numeric', 'float', column_type[1], ('::' + column_type[1])), ('float8', 'float', column_type[1], ('::' + column_type[1])), ('float8', 'monetary', column_type[1], ('::' + column_type[1]))]
                        if ((f_pg_type == 'varchar') and (field.type == 'char') and f_pg_size and ((field.size is None) or (f_pg_size < field.size))):
                            try:
                                with cr.savepoint():
                                    cr.execute(('ALTER    TABLE    "%s"    ALTER    COLUMN    "%s"    TYPE    %s' % (self._table, name, column_type[1])), log_exceptions=False)
                            except psycopg2.NotSupportedError:
                                cr.execute(('ALTER    TABLE    "%s"    RENAME    COLUMN    "%s"    TO    temp_change_size' % (self._table, name)))
                                cr.execute(('ALTER    TABLE    "%s"    ADD    COLUMN    "%s"    %s' % (self._table, name, column_type[1])))
                                cr.execute(('UPDATE    "%s"    SET    "%s"=temp_change_size::%s' % (self._table, name, column_type[1])))
                                cr.execute(('ALTER    TABLE    "%s"    DROP    COLUMN    temp_change_size    CASCADE' % (self._table,)))
                            cr.commit()
                            _schema.debug("Table    '%s':    column    '%s'    (type    varchar)    changed    size    from    %s    to    %s", self._table, name, (f_pg_size or 'unlimited'), (field.size or 'unlimited'))
                        for c in casts:
                            if ((f_pg_type == c[0]) and (field.type == c[1])):
                                if (f_pg_type != column_type[0]):
                                    converted = True
                                    try:
                                        with cr.savepoint():
                                            cr.execute(('ALTER    TABLE    "%s"    ALTER    COLUMN    "%s"    TYPE    %s' % (self._table, name, c[2])), log_exceptions=False)
                                    except psycopg2.NotSupportedError:
                                        cr.execute(('ALTER    TABLE    "%s"    RENAME    COLUMN    "%s"    TO    __temp_type_cast' % (self._table, name)))
                                        cr.execute(('ALTER    TABLE    "%s"    ADD    COLUMN    "%s"    %s' % (self._table, name, c[2])))
                                        cr.execute(('UPDATE    "%s"    SET    "%s"=    __temp_type_cast%s' % (self._table, name, c[3])))
                                        cr.execute(('ALTER    TABLE    "%s"    DROP    COLUMN        __temp_type_cast    CASCADE' % (self._table,)))
                                    cr.commit()
                                    _schema.debug("Table    '%s':    column    '%s'    changed    type    from    %s    to    %s", self._table, name, c[0], c[1])
                                break
                        if (f_pg_type != column_type[0]):
                            if (not converted):
                                i = 0
                                while True:
                                    newname = ((name + '_moved') + str(i))
                                    cr.execute('SELECT    count(1)    FROM    pg_class    c,pg_attribute    a    WHERE    c.relname=%s    AND    a.attname=%s    AND    c.oid=a.attrelid    ', (self._table, newname))
                                    if (not cr.fetchone()[0]):
                                        break
                                    i += 1
                                if f_pg_notnull:
                                    cr.execute(('ALTER    TABLE    "%s"    ALTER    COLUMN    "%s"    DROP    NOT    NULL' % (self._table, name)))
                                cr.execute(('ALTER    TABLE    "%s"    RENAME    COLUMN    "%s"    TO    "%s"' % (self._table, name, newname)))
                                cr.execute(('ALTER    TABLE    "%s"    ADD    COLUMN    "%s"    %s' % (self._table, name, column_type[1])))
                                cr.execute(('COMMENT    ON    COLUMN    %s."%s"    IS    %%s' % (self._table, name)), (field.string,))
                                _schema.warning('Table    `%s`:    column    `%s`    has    changed    type    (DB=%s,    def=%s),    data    moved    to    column    `%s`', self._table, name, f_pg_type, field.type, newname)
                        if (field.required and (f_pg_notnull == 0)):
                            if has_rows:
                                self._init_column(name)
                            try:
                                cr.commit()
                                cr.execute(('ALTER    TABLE    "%s"    ALTER    COLUMN    "%s"    SET    NOT    NULL' % (self._table, name)), log_exceptions=False)
                                _schema.debug("Table    '%s':    column    '%s':    added    NOT    NULL    constraint", self._table, name)
                            except Exception:
                                msg = "Table    '%s':    unable    to    set    a    NOT    NULL    constraint    on    column    '%s'    !\nIf    you    want    to    have    it,    you    should    update    the    records    and    execute    manually:\nALTER    TABLE    %s    ALTER    COLUMN    %s    SET    NOT    NULL"
                                _schema.warning(msg, self._table, name, self._table, name)
                            cr.commit()
                        elif ((not field.required) and (f_pg_notnull == 1)):
                            cr.execute(('ALTER    TABLE    "%s"    ALTER    COLUMN    "%s"    DROP    NOT    NULL' % (self._table, name)))
                            cr.commit()
                            _schema.debug("Table    '%s':    column    '%s':    dropped    NOT    NULL    constraint", self._table, name)
                        indexname = ('%s_%s_index' % (self._table, name))
                        cr.execute('SELECT    indexname    FROM    pg_indexes    WHERE    indexname    =    %s    and    tablename    =    %s', (indexname, self._table))
                        res2 = cr.dictfetchall()
                        if ((not res2) and field.index):
                            cr.execute(('CREATE    INDEX    "%s_%s_index"    ON    "%s"    ("%s")' % (self._table, name, self._table, name)))
                            cr.commit()
                            if (field.type == 'text'):
                                msg = "Table    '%s':    Adding    (b-tree)    index    for    %s    column    '%s'.This    is    probably    useless    (does    not    work    for    fulltext    search)    and    prevents    INSERTs    of    long    texts    because    there    is    a    length    limit    for    indexable    btree    values!\nUse    a    search    view    instead    if    you    simply    want    to    make    the    field    searchable."
                                _schema.warning(msg, self._table, field.type, name)
                        if (res2 and (not field.index)):
                            cr.execute(('DROP    INDEX    "%s_%s_index"' % (self._table, name)))
                            cr.commit()
                            msg = "Table    '%s':    dropping    index    for    column    '%s'    of    type    '%s'    as    it    is    not    required    anymore"
                            _schema.debug(msg, self._table, name, field.type)
                        if (field.type == 'many2one'):
                            comodel = self.env[field.comodel_name]
                            if (comodel._auto and (comodel._table != 'ir_actions')):
                                self._m2o_fix_foreign_key(self._table, name, comodel, field.ondelete)
                else:
                    cr.execute(('ALTER    TABLE    "%s"    ADD    COLUMN    "%s"    %s' % (self._table, name, field.column_type[1])))
                    cr.execute(('COMMENT    ON    COLUMN    %s."%s"    IS    %%s' % (self._table, name)), (field.string,))
                    _schema.debug("Table    '%s':    added    column    '%s'    with    definition=%s", self._table, name, field.column_type[1])
                    if has_rows:
                        self._init_column(name)
                    if field.compute:
                        stored_fields.append(field)
                    if ((field.type == 'many2one') and field.store):
                        if (field.comodel_name not in self.env):
                            raise ValueError((_('There    is    no    reference    available    for    %s') % (field.comodel_name,)))
                        comodel = self.env[field.comodel_name]
                        if (comodel._auto and (comodel._table != 'ir_actions')):
                            self._m2o_add_foreign_key_checked(name, comodel, field.ondelete)
                    if field.index:
                        cr.execute(('CREATE    INDEX    "%s_%s_index"    ON    "%s"    ("%s")' % (self._table, name, self._table, name)))
                    if field.required:
                        try:
                            cr.commit()
                            cr.execute(('ALTER    TABLE    "%s"    ALTER    COLUMN    "%s"    SET    NOT    NULL' % (self._table, name)))
                            _schema.debug("Table    '%s':    column    '%s':    added    a    NOT    NULL    constraint", self._table, name)
                        except Exception:
                            msg = "WARNING:    unable    to    set    column    %s    of    table    %s    not    null    !\nTry    to    re-run:    openerp-server    --update=module\nIf    it    doesn't    work,    update    records    and    execute    manually:\nALTER    TABLE    %s    ALTER    COLUMN    %s    SET    NOT    NULL"
                            _logger.warning(msg, name, self._table, self._table, name, exc_info=True)
                    cr.commit()
    else:
        cr.execute("SELECT    relname    FROM    pg_class    WHERE    relkind    IN    ('r','v')    AND    relname=%s", (self._table,))
        create = (not bool(cr.fetchone()))
    cr.commit()
    if self._auto:
        self._add_sql_constraints()
    if create:
        self._execute_sql()
    if parent_store_compute:
        self._parent_store_compute()
        cr.commit()
    if stored_fields:
        def func():
            fnames = [f.name for f in stored_fields]
            _logger.info('Storing    computed    values    of    %s    fields    %s', self._name, ',    '.join(sorted(fnames)))
            recs = self.with_context(active_test=False).search([])
            if recs:
                recs.invalidate_cache(fnames, recs.ids)
                for f in stored_fields:
                    recs._recompute_todo(f)
        todo_end.append((1000, func, ()))
