0

The following works when run in the context of a flask app executed in Jenkins:

A function is imported from one file to another:

def return_countries(db):
    db.session.expire_on_commit = False
    q = db.session.query(Country.countrycode).distinct().all()
    q = [t[0] for t in q]
    return q

Inside the file where it is imported I call it like this:

print(return_countries(db))

When this job is run in Jenkins, it works, no problems.

The thing is, I want one database call and then to use the returned list of country codes multiple times, not unnecessary keep querying the same thing. To keep it neat have tried to put it in a class. Yes, it could be done without the class but it may be needed in several parts of the code base, maybe with additional methods so would be cleaner if the class would work.

So I commented out that function definition and inserted the following class into the one file:

class checkCountries:
    def __init__(self, db):
        db.session.expire_on_commit = False
        __q = db.session.query(Country.countrycode).distinct().all()
        __q = [t[0] for t in __q]
        print(__q)

    def check(self, __q, countrycode):
        if countrycode in __q:
            return True
        else:
            return False

...updated the import statement in the other file and instantiated like this directly under the import statements:

cc = checkCountries(db)

and replaced the above print statement with this one:

print('check for DE: ', cc.check('DE'))
print('check for ES: ', cc.check('ES'))
print('check for GB: ', cc.check('GB'))

But it generated an error in the Jenkins log. The traceback is very long but below are what are probably the relevant excerpts.

Any ideas? Have a feeling something is wrong with what I have done with __q

/python3.6/site-packages/sqlalchemy/util/_collections.py", line 988, in __call__
15:26:01     return self.registry[key]
15:26:01 KeyError: 123456789123456
15:26:01 
15:26:01 During handling of the above exception, another exception occurred:
15:26:01 
15:26:01 Traceback (most recent call last):

/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 922, in get_app
15:26:01     raise RuntimeError('application not registered on db '
15:26:01 RuntimeError: application not registered on db instance and no application bound to current context
15:26:02 Build step 'Execute shell' marked build as failure
15:26:02 Finished: FAILURE
cardamom
  • 6,873
  • 11
  • 48
  • 102

1 Answers1

0

I got it to work, so here is the class I am using which now works:

class checkCountries:
    def __init__(self, db, app):
        db.init_app(app)
        with app.app_context():
            db.session.expire_on_commit = False
            self.__q = db.session.query(Country.countrycode).distinct().all()
        self.__q = [t[0] for t in self.__q]
        print(self.__q)

    def check(self, countrycode):
        if countrycode in self.__q:
            return True
        else:
            return False

Then, the line which instantiates it now takes 2 arguments:

cc = checkCountries(db, app)

The rest is the same as in the question above.

This answer from @mark_hildreth helped, thanks!

Yes, there were more than one thing wrong with it. The class wasn't quite right but debugged that in a simplified app and got it working but this error message specific to sqlalchemy was still there.

Maybe it had something to do with the variables in scope in the class vs in the function that stopped it binding to the Flask application context

cardamom
  • 6,873
  • 11
  • 48
  • 102