SQLAlchemy - execution of search term results in object

Viewed 50

I am executing my search term against my session and saving the collection of results in 'sw'. Then, for each match I want to print the matching contact, but I am getting an object. I have spent a few days trying to poke around and access the information inside the object, but so far my research skills have failed me.

If anyone could show me what I am missing, that would help.

Ultimately I want to be able to call a search term and then populate a ui element for each result, so I need to be able to access the attributes of the matched contacts, such as account, fName, email and so on.

My code:


        term = select([Contacts]).where((Contacts.account == skey) | (Contacts.fName == skey) |
                                        (Contacts.lName == skey) | (Contacts.phone == skey) | (Contacts.address == skey) |
                                        (Contacts.company == skey) | (Contacts.email == skey))
        sw = session.execute(term)

        if option == '0':
            print(f'0 - Search session,  Search Key: \'{skey}\'')

            if sw:
                for contact in sw:
                    print(f"Contact match: {contact}")

The issue is evident in the output. The Contacts object. I have tried help() and .__dict__ and others, but I can't access the contacts different information fields.

I have also tried the .notation such as contact.email, but get the error:

Exception has occurred: AttributeError
Could not locate column in row for column 'email'

My output:

0 - Search session,  Search Key: 'T'
Contact match: (<__main__.Contacts object at 0x000001906B3DA3D0>,)

1 Answers

The result of your query, sw, is an iterator of SQLAlchemy Row objects. When you loop over sw and print contact, you're really printing these Row objects, which is the tuple with your ORM object inside it that you see.

To get back a list of ORM objects directly (instead of Row objects), use the scalars() method:

sw = session.execute(term).scalars().all()

Read more in SQLAlchemy's documentation:

When selecting a list of single-element rows containing ORM entities, it is typical to skip the generation of Row objects and instead receive ORM entities directly, which is achieved using the Result.scalars() method

You still have one more problem though - Python doesn't know how to print your Contacts ORM object, so it just defaults to printing its name and memory address (like you see). To correct for this, you can define a __repr__ magic method on the ORM class. This allows you to define how Python evaluates a string representation of your object. Something like this in your case:

class Contacts(Base):
    ...

    def __repr__(self):
        return f"{self.fName} {self.lName}"

Read more about __repr__ in Python's documentation here.

Related