AttributeError: Could not locate column in row for column 'to_dict

AttributeError: Could not locate column in row for column 'to_dict

Stepan123Stepan123 Posts: 10Questions: 3Answers: 0
edited June 2022 in Free community support

I use flask with datatable.js plugin with ajax. I am getting following error. Looks like this error is thrown at the end of my view (see code at the bottom). I am not able to locate the cause of issue, any thoughts?

Error: (thrown from view shown below in code)

  'data': [it.to_dict() for it in query],
AttributeError: Could not locate column in row for column 'to_dict'

This is my model:

class DiskSpaceView(Database.db.Model, UserMixin):
    __tablename__ = 'view_space'
    __table_args__ = {"schema":"config"}
    column_not_exist_in_db = Database.db.Column(Database.db.Integer, primary_key=True) # just add for sake of this error, dont add in db
    object_type = Database.db.Column(Database.db.String)
    schemaname = Database.db.Column(Database.db.String)
    tablename = Database.db.Column(Database.db.String)
    indexname = Database.db.Column(Database.db.String)
    object_size_bytes = Database.db.Column(Database.db.String)
    object_size = Database.db.Column(Database.db.String)

    def to_dict(self):
        return {
            'column_not_exist_in_db': random.getrandbits(64),
            'object_type': self.object_type,
            'schemaname': self.schemaname,
            'tablename': self.tablename,
            'indexname': self.indexname,
            'object_size_bytes': self.object_size_bytes,
            'object_size': self.object_size
        }    

This is my Ajax call:

  $(document).ready(function () {
    var table = $("#dataTbDiskSpace").DataTable({
      scrollY: "600px",
      scrollCollapse: true,
      paging: true,
      ajax: "/api/datadiskspace",
      serverSide: true,
      pageLength : 200,
      success: function (ajax) {
        console.log("test.js >> DataTable ajax >>>" + JSON.stringify(ajax));
      },
      columns: [
        { data: "object_type" },
        { data: "schemaname"},
        { data: "tablename"},     
        { data: "indexname"},
        { data: "object_size_bytes"},    
        { data: "object_size"}
      ],
      columnDefs: [
        {
          defaultContent: "-",
          targets: "_all",
        },
      ],
    });
  });

This is my view:

@userviews.route('/api/datadiskspace')
def datadiskspace():                    
    query = DiskSpaceView.query.with_entities(DiskSpaceView.object_type, DiskSpaceView.schemaname, DiskSpaceView.tablename,DiskSpaceView.indexname,DiskSpaceView.object_size_bytes, DiskSpaceView.object_size)
    print(query)
    # search filter
    search = request.args.get('search[value]')
    if search:
        query = query.filter(DatabasePostgres.db.or_(
            DiskSpaceView.tablename.like(f'%{search}%'),
            DiskSpaceView.indexname.like(f'%{search}%')
        ))
    total_filtered = query.count()

    # sorting
    order = []
    i = 0
    while True:
        col_index = request.args.get(f'order[{i}][column]')
        if col_index is None:
            break
        col_name = request.args.get(f'columns[{col_index}][data]')
        if col_name not in ['object_type', 'schemaname', 'tablename', 'indexname','object_size_bytes','object_size']:
            col_name = 'schemaname'
        descending = request.args.get(f'order[{i}][dir]') == 'desc'
        col = getattr(DiskSpaceView, col_name)
        if descending:
            col = col.desc()
        order.append(col)
        i += 1
    if order:
        query = query.order_by(*order)

    # pagination
    start = request.args.get('start', type=int)
    length = request.args.get('length', type=int)
    query = query.offset(start).limit(length)

    #debug
    counter = 1
for i in query:
        print(i)           
        print(counter)
        counter += 1


    # response
    return {
        'data': [it.to_dict() for it in query],
        'recordsFiltered': total_filtered,
        'recordsTotal': DiskSpaceView.query.count(),
        'draw': request.args.get('draw', type=int)
    }

I think it may something to do with pagination - if i set for example 200 in my ajax call like: pageLength : 200 then in my view when i print (see #debug) it prints me 200 rows. When I for instance change to pageLength : 50. My print loop prints me 50 rows... I don't understand what's the case but this seems to be pretty intresting.

Answers

  • Stepan123Stepan123 Posts: 10Questions: 3Answers: 0

    I may find another possible cause of that issue. In the view when i want to exclude one of my column from model (column_not_exist_in_db) i use with_entites to achieve that as follows:

    query = DiskSpaceView.query.with_entities(DiskSpaceView.object_type, DiskSpaceView.schemaname, DiskSpaceView.tablename,DiskSpaceView.indexname,DiskSpaceView.object_size_bytes, DiskSpaceView.object_size)
    

    Ive just read that with_entites gives me tuples instead of real model object so i tried to change it to:

     query = DiskSpaceView.query.options(load_only('object_type', 'schemaname','tablename', 'indexname','object_size_bytes', 'object_size'))
    

    once i did i am getting error:

    sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedColumn) column v_disc_spaces.column_not_exist_in_db does not exist
    LINE 2: FROM (SELECT config.view_space.column_not_exist_in_db AS ...
    

    load_only seems to solve my issue as looks like it get model object but why then it throws this error as i excluded column_not_exist_in_db column ?

Sign In or Register to comment.