3

I'm trying to add a unique constraint in a parent class in Flask-SQLAlchemy in the next way. As you see, the inheritance is represeted in the Joined Table way.

class Parametric(object, Model):
  __tablename__ = "parametric"
  __mapper_args__ = {'polymorphic_on': type,
                     'polymorphic_identity': 'Parametric'}
  __table_args__ = (
         db.UniqueConstraint('name', 'type', name='name_type'),
     )
  id = Column(db.Integer, primary_key=True)
  name = Column(db.String(32), nullable=False)
  type = Column(db.String(50)) 

  def __init__(self, name):
   self.name = name


class Bar(Parametric):        
  __tablename__ = "bar"
  __mapper_args__ = {'polymorphic_identity': 'Foo'}
  prop = Column(db.String(32), nullable=False)
  id = db.Column(db.Integer, db.ForeignKey('parametric.id'), primary_key=True)

  def __init__(self, name, prop):
   super(Parametric, self).__init__(name=name)
   self.prop = prop

When the first child is read by the interpreter, i get the next traceback:

  File "/usr/local/lib/python2.7/dist-packages/Flask_SQLAlchemy-1.0-py2.7.egg/flask_sqlalchemy/__init__.py", line 510, in __init__
    DeclarativeMeta.__init__(self, name, bases, d)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/api.py", line 53, in __init__
    _as_declarative(cls, classname, cls.__dict__)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py", line 251, in _as_declarative
    **table_kw)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/sql/schema.py", line 352, in __new__
    table._init(name, metadata, *args, **kw)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/sql/schema.py", line 429, in _init
    self._init_items(*args)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/sql/schema.py", line 72, in _init_items
    item._set_parent_with_dispatch(self)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/sql/base.py", line 421, in _set_parent_with_dispatch
    self._set_parent(parent)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/sql/schema.py", line 2272, in _set_parent
    ColumnCollectionMixin._set_parent(self, table)
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/sql/schema.py", line 2240, in _set_parent
    col = table.c[col]
  File "/usr/local/lib/python2.7/dist-packages/SQLAlchemy-0.9.4-py2.7-linux-x86_64.egg/sqlalchemy/util/_collections.py", line 156, in __getitem__
    return self._data[key]
KeyError: 'name'

Any solution? is there something wrong in my code?

Hamlett
  • 403
  • 6
  • 22

1 Answers1

0

In SQLAlchemy, you can specify a Column to be unique with the unique=True parameter. I think that would be a preferred, more readable way of doing things.

I think your problem is to do with inheritance, possibly syntax.

In your Parametic's __init__() function, you have name. Notice that name is an arg, not a kwarg. Instead of using name=name, just submit name like so:

super(Parametric, self).__init__(name)
NuclearPeon
  • 5,743
  • 4
  • 44
  • 52
  • unique=True is for single columns, I need to create a unique compund constraint. name=name is an explicit way to pass the parameter. – Hamlett Nov 11 '15 at 22:48
  • @Jp_uy Does this help? http://stackoverflow.com/questions/10059345/sqlalchemy-unique-across-multiple-columns -- It looks like your unique constraint is correct, does fixing the `__init__` method fix the problem? – NuclearPeon Nov 11 '15 at 23:20
  • 1
    This is almost what I want to do, in fact, what I'm doing but with the little difference that I have inheritance. The inheritance is what is complicating in my case. To be more specific, class Parametric is the parent of Bar. I want to set the unique constraint in the Parent but when the child is read by the interpreter, it tries to create it from the child (I mean, taking just the child attributes) and fails. – Hamlett Nov 13 '15 at 17:55