Home > Net >  Is there a way to pass a class/instance attribute name as a variable?
Is there a way to pass a class/instance attribute name as a variable?

Time:03-11

I am using a class to model and manage a database table, but due to the nature of the data I am usually only updating a single column (attribute) at a time. Is there a way to pass which column (attribute) to update?

Example: Let's say I'm making a log of who has last used an access point.

Base = declarative_base()
class Log(Base):
   __tablename__ = "log"
   id = Column(Integer, primary_key=True)
   access_point = Column(Integer, unique=True)
   admin = Column(String)
   staff = Column(String)
   consult = Column(String)
   visitor = Column(String)

I want a way to pass which user_type (admin/staff/consult/visitor) to an aux function to handle the insertion/updating, including the creation of new access_points, something like:

def db_update(a_p, user_info, user_type):
   q = session.query(Log).filter(Log.access_point == a_p)
   if session.query(q.exists()).scalar():
        stmt = update(Log).where(Log.access_point == a_p).values(user_type=user_info)
        session.execute(stmt)
   else:
        new_point = Log(access_point = a_p, user_type = user_info)
        session.add(new_point)

Is there a way of doing this other than just passing a comparator of some sort to pick the user_type (i.e. "if user_type == 1, update admin" sort of thing)?

CodePudding user response:

Have your function accept the columns names and values as keyword arguments, and pass them directly to the values method or the model's initialiser.

def db_update(a_p, **values):
   q = session.query(Log).filter(Log.access_point == a_p)
   if session.query(q.exists()).scalar():
        stmt = update(Log).where(Log.access_point == a_p).values(**values)
        session.execute(stmt)
   else:
        new_point = Log(access_point = a_p, **values)
        session.add(new_point)

db_update(1, admin='Alice')

If your table should gain additional columns you will be able to update them without changing the function code.

CodePudding user response:

You could use a dictionary.

Here's an example with some mock functions:

def update_admin():
    return 1
def update_staff():
    return 2
def update_consult():
    return 3
def update_visitor():
    return 4


update_dict = {
    'admin': update_admin,
    'staff': update_staff,
    'consult': update_consult,
    'visitor': update_visitor}


print(update_dict['staff']())
# 2

print(update_dict['visitor']())
# 4

  • Related