Reputation: 797
I'm trying to sort out how to add a context sensitive function (e.g. def get_user_full_name()) that will get triggered from the default and onupdate specifications on a column. I'm trying to set a composite field that combines the first and last names into a single full name value to avoid having to constantly concat the two fields in all queries.
I'm using the declarative approach. This is an example of a similar model:
class SomeMembers(Base):
__tablename__ = 'some_members'
__table_args__ = {'mysql_engine':'InnoDB'}
SomeGroup = Column(Unicode(50), primary_key=True)
UserID = Column(Unicode(50), primary_key=True)
FullName = Column(Unicode(255), default=get_user_full_name, onupdate=get_user_full_name, index=True)
FirstName = Column(Unicode(255), index=True)
LastName = Column(Unicode(255), index=True)
UserName = Column(Unicode(255))
This is the function that I wrote which reports in the stack trace that neither the FirstName or LastName keys are valid:
def get_user_full_name(context):
return " ".join((context.compiled_parameters[0]['FirstName'],context.compiled_parameters[0]['LastName']))
It isn't clear to me how I can reference the two columns (FirstName and LastName) existing data to create a composite value to store for easy retrieval. For example, if I had a user named John Doe the get_user_full_name method should take "John" and "Doe" and return a full name value of "John Doe".
In the documentation it refers to context.current_parameters but that does not exist in my case. I suspect it is because we use the declarative approach. If it did work my get_user_full_name function would look like:
def get_user_full_name(context):
return " ".join((context.current_parameters['FirstName'],context.current_parameters['LastName']))
I know this is probably trivial but I can't seem to crack the code on where this information is stored and how to access it dynamically.
A little insight would be much appreciated. I'm also open to a more elegant approach too.
Thanks in advance...
Cheers,
Paul
Upvotes: 4
Views: 1133
Reputation: 351
Just in case somebody is looking for an answer.
You can use mapper-events
@event.listens_for(SomeMembers, 'before_insert')
def before_insert_function(mapper, connection, target):
target.FullName = f"{target.FirstName} {target.LastName}"
Upvotes: 2
Reputation: 16085
I tried the following expression:
from sqlalchemy.sql.expression import column, literal, literal_column
Column('full_name', String, onupdate=literal_column("first_name") + literal(" ") + literal_column("last_name"))
It sort of works, but updates the full_name
with the previous values of first_name
and last_name
. Using column
yields the same result.
Would a composite column do the job?
Upvotes: 0