In some cases you may not know the table for a Pynamo model until you instantiate it. You can’t do this when you construct the object, but you can create a static method that takes the model class and table name and sets model.Meta.table_name to the table_name parameter, changing the table that model is connected to. This is useful if you set up models in one module and then import it elsewhere, and the table names come from user input.
from pynamodb import Model
from pynamodb.attributes import UnicodeAttribute
class AttributesModel(Model):
class Meta:
region = "us-east-1"
attribute_id = UnicodeAttribute(hash_key=True)
attribute_name = UnicodeAttribute()
attribute_value = UnicodeAttribute()
@staticmethod
def setup_model(model, table_name):
model.Meta.table_name = table_name
Tweet#
If you’re building AWS applications in Python, have you tried Pynamo for making DynamoDB queries less hellish? In most cases, you need to know the table name or ARN when you create the model, or at least fill it with an environment variable. A typical model might look like this:
from pynamodb.models import Model
from pynamodb.attributes import UnicodeAttribute, NumberAttribute, BooleanAttribute
class UserModel(Model):
class Meta:
table_name = os.getenv("USER_TABLE", "audiences")
user_id = UnicodeAttribute(hash_key=True)
last_logged_in = NumberAttribute()
banned = BooleanAttribute()

But what if you won’t know the table name until you use the model? This poses a problem if you import your model into another module or use user input to get a table name. Luckily, it has a simple fix. Instead of setting table_name in the Meta class definition, you can declare a setup_model static method that takes the model class and now-known table name as arguments. You can then set the table_name on the Meta class:
from pynamodb.models import Model
from pynamodb.attributes import UnicodeAttribute, NumberAttribute, BooleanAttribute
class UserModel(Model):
class Meta:
table_name = os.getenv("USER_TABLE", "audiences")
user_id = UnicodeAttribute(hash_key=True)
last_logged_in = NumberAttribute()
banned = BooleanAttribute()
@staticmethod
def setup_model(model, table_name):
model.Meta.table_name = table_name

Now the table name is separate from instantiating the model, so you can supply it once your code has it:
from models import UserModel
table = function_that_gets_table_name()
UserModel.setup_model(model=UserModel, table_name=table)
user = UserModel.get("69")
