association_proxy requires specific __init__ signature

Issue #647 resolved
Former user created an issue

This may be a defect or it may be a documentation issue.

I tried to use the association proxy where my association class looked very similar to this:

class MyClass(object): def init( self, **kwargs ): doSomethingWith( kwargs )

When I tried to do this with the association proxy, I got an exception.

I replicated the problem using the Article/Keywords example from the documentation and sqlalchemy from the trunk (rev 2883). I've attached the code that will replicate the problem. A workaround was to add args to the init signature:

class MyClass(object): def init( self, args, *kwargs ): doSomethingWith( kwargs )

C:\Program Files (x86)\Python\lib\site-packages\sqlalchemy-0.3.9dev_r2883-py2.5.egg\sqlalchemy\databases\sqlite.py:168: RuntimeWarning: The installed version of sqlite (3.3.4) is out-dated, and will cause errors in some cases.  Version 3.3.13 or greater is recommended.
  warnings.warn(RuntimeWarning("The installed version of sqlite (%s) is out-dated, and will cause errors in some cases.  Version 3.3.13 or greater is recommended." % self.dbapi.sqlite_version))
Traceback (most recent call last):
  File "sqlalchemy_associationproxy_fails.py", line 63, in <module>
    article.keywords.append(Keyword('blue'))
  File "c:\program files (x86)\python\lib\site-packages\SQLAlchemy-0.3.9dev_r2883-py2.5.egg\sqlalchemy\ext\associationproxy.py", line 304, in append
    item = self._create(value, **kw)
  File "c:\program files (x86)\python\lib\site-packages\SQLAlchemy-0.3.9dev_r2883-py2.5.egg\sqlalchemy\ext\associationproxy.py", line 251, in _create
    return self.creator(value, **kw)
  File "c:\program files (x86)\python\lib\site-packages\SQLAlchemy-0.3.9dev_r2883-py2.5.egg\sqlalchemy\orm\mapper.py", line 691, in init
    oldinit(self, *args, **kwargs)
TypeError: __init__() takes exactly 1 argument (2 given)

Comments (4)

  1. jek

    Types for sequence associations are instantiated with a single positional argument (value), and dict associations get two positionals (key and value). The documentation for the calling signature is mixed in with discussion of 'creator' functions, and should be mentioned more explicitly. Thanks!

  2. jek

    Also, if you have a type that you want to associate and it only takes keyword arguments, then you do want to supply a creator function to adapt the signature. Something like:

    # for a dict association
    def make_myclass(key, value):
      return MyClass(fribbity=key, frobbity=value)
    
  3. Log in to comment