Difficulty to pass update column as parameter in Python3 function with Sqlalchemy

Asked

Viewed 24 times

-1

I’m using Sqlalchemy to work with database tables. I am creating classes for the proper tables, where I have as methods of these classes, Insert, filter_all(), etc.

I’m using the following class with your methods:

class Veiculos(base):
    __tablename__ = "veiculos"

    id = Column(Integer, primary_key=True, autoincrement=True)
    marca =  Column(String(20))
    modelo = Column(String(20))
    ano = Column(Integer)

    def __init__(self, str_marca="None", str_modelo="None", int_ano="None"):
        """
        :param str_marca: (str).
        :param str_modelo: (str).
        :param  int_ano: (int).
        """
        self.marca =  str_marca
        self.modelo = str_modelo
        self.ano = int_ano

    def __repr__(self):
        return "< Veículo {}, {}, {} >".format(self.marca, self.modelo, self.ano)

    def insert(self):
        session.add(self)
        session.commit()

    @classmethod
    def filter_by(self, **kwargs):
        return  session.query(self).filter_by(**kwargs).all()

    @classmethod
    def select_all(self):        
        return session.query(self)

    @classmethod
    def update(self, int_id, **kwargs):
        id = int_id
        print('keys', kwargs.keys())
        print('values', kwargs.values())
        print('-----')
        print('Nome ANTES da alteração:', session.query(self).filter_by(id=id).one().marca)
        session.query(self).filter_by(id=id).update(**kwargs)
        # session.query(self).filter_by(id=id).update(**kwargs)
        # session.commit()
        print('Nome DEPOIS da alteração:', session.query(self).filter_by(id=id).one().marca)

My problem is in the following method:

@classmethod
        def update(self, int_id, **kwargs):
            id = int_id
            print('keys', kwargs.keys())
            print('values', kwargs.values())
            print('-----')
            print('Nome ANTES da alteração:', session.query(self).filter_by(id=id).one().marca)
            session.query(self).filter_by(id=id).update(**kwargs)
            # session.query(self).filter_by(id=id).update(**kwargs)
            # session.commit()
            print('Nome DEPOIS da alteração:', session.query(self).filter_by(id=id).one().marca)

Specifically on these lines:

session.query(self).filter_by(id=id).update(**kwargs)
session.commit()

Where the filter_by(id=id) correctly search, but the part update(**kwargs) says there is no argument.

Erro:
Nome ANTES da alteração: CLEBER
Traceback (most recent call last):
  File "c:/Projetos/estudoPostgres11/SAO.py", line 97, in <module>
    veiculos.update(id, **busca)
  File "c:/Projetos/estudoPostgres11/SAO.py", line 52, in update
    session.query(self).filter_by(id=id).update(**kwargs)
TypeError: update() got an unexpected keyword argument 'marca'

This is the call of the function:

veiculos = Veiculos()
    id = 1
    busca = {"marca": "TUDO"}
    veiculos.update(id, **busca)

What I’m doing wrong to not run the update that way?

  • And how would you run it manually session.query(self).filter_by(id=id).update(...)?

  • Manually it would read "Session.query(self). filter_by(id=id). update({column: value})." But passing this by parameter (**kwargs) in function did not work. I resolved otherwise: Put in general comment because here it does not fit

  • Okay, but did this manually work? Because your manual is DIFFERENT from your via kwargs, your manual is this .filter_by(id=id).update({coluna: valor}) and your kwargs is generating this .filter_by(id=id).update(coluna=valor), and I’m almost sure that this is not recognized by sqlalchemy, it only accepts past as Dict and is not what your kwargs is doing, it is passing as parameter

  • Manually it works. In the general comment (Reply), how I managed to get around.

  • No, you don’t understand, manually this different from the kwargs, you understand one thing the kwargs is not being interpreted in the same way as the manual, you understand? The kwarg was supposed to generate this: .filter_by(id=id).update({coluna: valor}), but this dynamically, this should be the equivalent, BUT the way you wrote it is generating it INTERNALLY: .filter_by(id=id).update(coluna=valor), and this form here is incorrect.

  • But even if I did: . filter_by(id=id). update({kwargs.Keys(): kwargs.values()}) or similar did not work. You can look like I told you and tell me if I had anything better:

  • You’re inventing unreal syntaxes, it’s no use inventing things, it’s not how kwargs works, in the other answer I pasted the link and explained, you first need to understand how is manually and adjust point to point, python makes it easier in a lot of things, but is not able to guess random things, I am not criticizing, just saying, do not invent, this there is no, have to understand the functioning of language I will see if I adjust here and I formulate at once the answer, is that I do not like to give the fish ready, I’m trying to teach you how to fish it.

  • Yes, I understand. I appreciate the attention but I managed to resolve as published reply.

Show 3 more comments

1 answer

0


Resolved as follows:

@classmethod
    def update(self, int_id, **kwargs):
        id = int_id
        for e in kwargs:
            coluna = e
            valor = kwargs[e]                    
        print('Nome ANTES da alteração:', session.query(self).filter_by(id=id).one().marca)
        session.query(self).filter_by(id=id).update({coluna: valor})
        session.commit()
        print('Nome DEPOIS da alteração:', session.query(self).filter_by(id=id).one().marca)

The call went like this:

  veiculos = Veiculos()
    id = 1
    busca = {"marca": "TUDO"}
    veiculos.update(id, **busca)

If you have anything better, I’ll be glad to know.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.