I have a base Dataset class that I'd like to dynamically inherit from. When 
a user uploads a new dataset, I create a new table as shown below, and 
populate it with data. My two most common use-cases:

   1. Retrieving entire dataset. I want to return dataset_x where x is an 
   integer that corresponds to experiment_id
   2. Searching through all datasets. I query against the parent datasets table 
   and apply filters as needed.

The issue is that when I need to retrieve a dataset, I need to run through 
my create_dataset function once more. This isn't such a big deal for use 
case #1, I just do create_dataset(x). However, for case #2, I need to loop 
through the whole set of child tables. My question is: is there a way 
around this? Additionally, please tell me if what I'm doing is basically 
pointless.. my child classes do not add additional attributes. I chose this 
route because it seemed to make sense based on my two use cases above. Each 
dataset is on the order of 10,000 rows, and I expect to have on the order 
of 10,000 datasets. Should I just stick to having an additional column for 
experiment_id and just filter against then in case #1?

I should note that I am using Flask-SQLAlchemy but I think this maps well 
to the pure SQLAlchemy case.. Please tell me if I'm off base on that 
assumption based on the below code. My parent class:

class Dataset(db.Model):
    __tablename__ = 'datasets'
    id = Column(db.Integer, primary_key=True)
    foo  = Column(db.Integer)
    bar = Column(db.String(20))
    experiment_id = Column(db.Integer)
    __mapper_args__ = {
        'polymorphic_identity': 'dataset',
        'polymorphic_on': experiment_id
    }

How I create new child classes dynamically:

def create_dataset(experiment_id):
    dataset_name = 'dataset_{}'.format(experiment_id)

    props = {
        '__tablename__': dataset_name,
        '__mapper_args__': {'polymorphic_identity': experiment_id},
        'id': db.Column(db.Integer, db.ForeignKey('datasets.id'), 
primary_key=True)
    }

    return type(
        dataset_name,
        (Dataset,),
        props
    )

The error that I run up against if I neglect running my dataset creation 
function:

AssertionError: No such polymorphic_identity 1 is defined

and the larger stack trace:

  File "/env/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 86
, in instances
    util.raise_from_cause(err)
  File "/env/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 
200, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/env/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 
184, in reraise
    raise value
  File "/env/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 71
, in instances
    rows = [proc(row) for row in fetch]
  File "/env/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 71
, in <listcomp>
    rows = [proc(row) for row in fetch]
  File "/env/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 
594, in polymorphic_instance
    _instance = polymorphic_instances[discriminator]
  File "/env/lib/python3.5/site-packages/sqlalchemy/util/_collections.py", 
line 728, in __missing__
    self[key] = val = self.creator(key)
  File "/env/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 
578, in configure_subclass_mapper
    discriminator)
AssertionError: No such polymorphic_identity 1 is defined

Thank you for the wonderful ORM!

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to