0

Research is at the bottom, read before -1'ing... Thanks.

I have to write a Python script that runs SQL queries. I made a main class and called SQLQuery. Each SQLQuery instance represents a query. The script must be structured like this:

class SQLQuery(object):

     def __init___(self, string_myQuery)...

instance1 = SQLQuery(SQLQuery1)...

instance2 = SQLQuery(SQLQuery2)...

As a user requirement, the instances must be in the same file as the class (so I can't just make each instance a main and execute that file separately), and each instance must be executed with Linux console commands. I can execute the entire script with a simple python SQLQuery.py but I need to execute each instance separately. The queries will be executed every day, automatically, so I don't need a terminal UI tree. It should be executed with a command similar to this:

python SQLQuery.py -inst1

will execute instance1.

python SQLQuery.py -inst2

will execute instance2.

I have researched how to execute Python scripts with Linux commands and most of the articles are about calling commands from the Python script. However, I found this article from the Python documentation. It suggests adding -m, so:

python SQLQuery.py -m inst1

This would let me set my main with a console command, but it doesn't work since the instances aren't modules. And since the instances must be in the same file as the class, I can't just import them as a module when I execute SQLQuery.py with a console command.

5
  • Why don't you just pass a command-line argument to the script that tells it which instance to run? Commented May 17, 2013 at 18:57
  • 2
    The structure you presented makes no sense. SQLQuery has itself as a base class, and also takes itself as an __init__ argument? Also, what are MainClass and SQLQuery1? Commented May 17, 2013 at 18:58
  • Also, where does that document suggest adding -m? It describes how -m works as an argument to python itself, where it means to find and execute a module by name; that doesn't imply anything at all about what -m should means as an argument to your script. Commented May 17, 2013 at 19:00
  • 2
    check out docs.python.org/2/library/argparse.html, build a command line interface Commented May 17, 2013 at 19:05
  • martineau, that's what I'm trying to do. You have described my question. abarnert, that is irrelevant. Commented May 17, 2013 at 19:25

2 Answers 2

1

Ignoring all the irrelevancies, it sounds like your problem is that you have a bunch of global objects named instance1, instance2, instance3, etc., and you want to call some method on one of them based on a command-line parameter whose value will be similar to, but not identical to, the instance names.

That's probably not a good idea… but it's not that hard:

if __name__ == '__main__':
    inst = sys.argv[1] # will be 'inst1', 'inst13', etc.
    inst_number = inst[5:] # so '1', '13', etc.
    inst_name = 'instance' + inst_number
    instance = globals()[inst_name]
    instance.execute()

A much better way to do the same thing is to put the instance globals into a list or dict that you can index.

For example, let's say instead of instance1, instance2, etc., you've got an instances dict, with instances['1'], instances[2], etc. Now instead of this:

inst_name = 'instance' + inst_number
instance = globals()[inst_name]
instance.execute()

… you just do this:

instances[inst_number].execute()

Also, instead of coming up with a command-line parameter that has extra stuff in it that you have to parse and throw away, and has no more meaning for a human reader than for your code, why not just take a number?

python myscript.py 12

Or, alternatively, use argparse to create an argument that can be used in all of the obvious ways:

python myscript.py --instance=12
python myscript.py --instance 12
python myscript.py -i12
python myscript.py -i 12

Either way, your code gets the string '12', which it can then use to look up the function, as above.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I would upvote it if I had more rep. Everyone else just picked apart irrelevancies and downvoted me because they they couldn't find the research I did at the bottom of the post. I guess next time I'll put my research all at the top. I'll try to put the instances in a dictionary. That seems like the simplest and cleanest solution, and it doesn't have to be human-readable since the command will be run by the server every day on a timer.
@JaneGoodall: As the questioner, it's more important to accept the right answer—or comment on the best one to explain how it can be improved before it's worth accepting—than to upvote.
1

You have the wrong syntax for the -m option. Suppose you have the following file named foo.py:

import sys
print 'First arg is: ', sys.argv[1]

Then you would call it like this:

$ python -m foo bar
First arg is:  bar

Note that the ".py" extension is omitted. You can then use the command line argument to decide which object to use or use the argparse or optparse module to handle the argument.

2 Comments

Thank you bogatron, but I cannot call an external file. It's a user requirement.
Perhaps I'm not understanding your question. I'm not suggesting you call an external file. The foo.py file above is your SQLQuery.py file. You use the command line argument to decide which object to use within the file. If you are trying to make command line calls to create new objects within an existing python process, then you should consider the python multiprocessing module, which will enable you to easily set up a server process that you can access from the command line to create new objects within a module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.