Trying to avoid using the "eval" command/statement

47 views
Skip to first unread message

Henry Versemann

unread,
Apr 15, 2015, 12:45:02 PM4/15/15
to django...@googlegroups.com
I have an incoming list of DB table names associated with my application. I want to iterate through this list of table names getting all of the entries for each table and then print some data from each tables' entry to a file. I've tried to write this so I can use it for as many app-associated tables as possible.

My problem is since the logic won't know which tables will be in the incoming list I need to try to reference the entries in each table using some kind of evaluated version of a variable containing the name of each table, as I iterate through the list.

I'm sure I could do this using an "eval" statement like this

tblComannd = "tblEntryLst = " + str(tableName) + ".objects.all()"

eval(tblComannd)

but I also know that the "eval" statement is not the safest thing to use.

So far I've tried to reference the table name in the following ways:

tblEntryLst = str(tableName).objects.all()
tblEntryLst = tableName.objects.all()

with no success at all and only an AttributeError exception being the result.

I think its possible since I've successfully done some similar things with referencing and saving the values of unknown keys for dictionaries similar to this:

new_dictionary[str(extracted_key)] = old_dictionary[str(extracted_key)]

but don't know this for sure.

Can someone please confirm if this is indeed possible to do or not, and if so give a general format or example for how to do it?

Any help would be much appreciated.

Thanks.

Henry
 

Stephen J. Butler

unread,
Apr 15, 2015, 12:51:33 PM4/15/15
to django...@googlegroups.com
Classes (MyModel) are attributes of the module (myapp.models). No
reason to use eval. You can get the module from importlib and then the
class from using getattr() on the module.

http://stackoverflow.com/questions/10773348/get-python-class-object-from-string
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/e3430efb-7fc2-4baf-931b-6ec8d8580315%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Stephen J. Butler

unread,
Apr 15, 2015, 12:53:09 PM4/15/15
to django...@googlegroups.com
Or, if you know all the Model classes are in the same module that
you've imported, it should be as easy as:

from myapp import models

model_class = getattr(models, tableName)

Tim Chase

unread,
Apr 15, 2015, 1:00:36 PM4/15/15
to django...@googlegroups.com
On 2015-04-15 09:45, Henry Versemann wrote:
> My problem is since the logic won't know which tables will be in
> the incoming list I need to try to reference the entries in each
> table using some kind of evaluated version of a variable containing
> the name of each table, as I iterate through the list.
>
> I'm sure I could do this using an "eval" statement like this
>
> tblComannd = "tblEntryLst = " + str(tableName) + ".objects.all()"
>
> eval(tblComannd)

Since it's just Python, you can create mappings of the table-objects,
and then get attributes on them.

table_names = {
"tblA": tblA,
"tblB": tblB,
"tblRenamed": tblXYZ,
}

for name, cls in table_names.items():
log.info("Dumping %s", name)
for item in cls.objects.all():
write_to_file(item)

Presumably, these classes come from some namespace like a module, so
you can even do something like

import models
table_names = ["tblA", "tblB"]
for name in table_names:
log.info("Dumping %s", name)
cls = getattr(models, name)
for item in cls.objects.all():
write_to_file(item)

-tim



Vijay Khemlani

unread,
Apr 15, 2015, 1:43:28 PM4/15/15
to django...@googlegroups.com
You can use get_model

from django.db.models.loading import get_model

YourModel = get_model('your_app', tableName)

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.

Henry Versemann

unread,
Apr 15, 2015, 4:10:05 PM4/15/15
to django...@googlegroups.com
Thanks for the help Stephen.

Henry Versemann

unread,
Apr 15, 2015, 4:32:45 PM4/15/15
to django...@googlegroups.com
Vijay,

I tried your method, and while it got me the table class that I wanted, for some reason when I try to get into the actual list of entries in the desired table, I can't seem to get to either the keys or values of any of the list objects.
So I'm not sure what's going on.
Here's some condensed code of what I've done so far:

            for entry in tblsLst:
                entryKeys = entry.keys()
                table_name = str(entryKeys[0])
                table_class = get_model('canvas_app',table_name)
                tblEntryLst = table_class.objects.all()
                lstLgth = len(tblEntryLst)
                for loopindx in range(lstLgth):
                    tblEntryObj = tblEntryLst[loopindx]
                    tblEntryObjKeys = tblEntryObj.keys()

And I seem to be getting an AttributeError exception on the last line above.
When I print the size or contents (table objects format (the objects are listed like this:

    <CanvasRequests: CanvasRequests object>

) no internal value to see) of the tblEntryLst everything looks right.
Is there anything you can suggest for determining where the problem might be?

Thanks for the help.

Henry

Vijay Khemlani

unread,
Apr 15, 2015, 4:39:26 PM4/15/15
to django...@googlegroups.com
tblEntryObj seems to be an instance of your model, it is not a dictionary, so normally it wouldn't have a "keys" method.

Henry Versemann

unread,
Apr 15, 2015, 4:49:58 PM4/15/15
to django...@googlegroups.com
ok.
Reply all
Reply to author
Forward
0 new messages