{"action":"closed","issue":{"url":"https://api.github.com/repos/sdispater/orator/issues/54","repository_url":"https://api.github.com/repos/sdispater/orator","labels_url":"https://api.github.com/repos/sdispater/orator/issues/54/labels{/name}","comments_url":"https://api.github.com/repos/sdispater/orator/issues/54/comments","events_url":"https://api.github.com/repos/sdispater/orator/issues/54/events","html_url":"https://github.com/sdispater/orator/issues/54","id":140439721,"number":54,"title":"Composite primary keys do not work","user":{"login":"joelbarker2011","id":1048165,"avatar_url":"https://avatars.githubusercontent.com/u/1048165?v=3","gravatar_id":"","url":"https://api.github.com/users/joelbarker2011","html_url":"https://github.com/joelbarker2011","followers_url":"https://api.github.com/users/joelbarker2011/followers","following_url":"https://api.github.com/users/joelbarker2011/following{/other_user}","gists_url":"https://api.github.com/users/joelbarker2011/gists{/gist_id}","starred_url":"https://api.github.com/users/joelbarker2011/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joelbarker2011/subscriptions","organizations_url":"https://api.github.com/users/joelbarker2011/orgs","repos_url":"https://api.github.com/users/joelbarker2011/repos","events_url":"https://api.github.com/users/joelbarker2011/events{/privacy}","received_events_url":"https://api.github.com/users/joelbarker2011/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-03-13T02:37:39Z","updated_at":"2016-03-24T20:53:25Z","closed_at":"2016-03-24T20:53:25Z","body":"It is possible to create a new model (with `schema.create`) that uses a composite primary key (with `table.primary(['column1', 'column2'])`). Unfortunately, it does not appear that it is possible to create a `Model` subclass that uses this composite key.\r\n\r\nSpecifying the composite key in the `Model` subclass with `__primary_key__ = ('column1', 'column2')` (using a **tuple**) results in this error:\r\n```\r\nTraceback (most recent call last):\r\n  File \"test.py\", line 39, in <module>\r\n    print w.serialize()\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 2146, in serialize\r\n    attributes = self.attributes_to_dict()\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 2168, in attributes_to_dict\r\n    attributes = self._get_dictable_attributes()\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 2207, in _get_dictable_attributes\r\n    return self._get_dictable_items(self._attributes)\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 2261, in _get_dictable_items\r\n    return {x: values[x] for x in values.keys() if x not in self.__hidden__ and not x.startswith('_')}\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 2261, in <dictcomp>\r\n    return {x: values[x] for x in values.keys() if x not in self.__hidden__ and not x.startswith('_')}\r\nAttributeError: 'tuple' object has no attribute 'startswith'\r\n```\r\n\r\nSpecifying the composite key in the `Model` subclass with `__primary_key__ = ['column1', 'column2']` (using a **list**) results in this error:\r\n```\r\nTraceback (most recent call last):\r\n  File \"test.py\", line 38, in <module>\r\n    w = Widget.create(column1=col1, column2=col2)\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 412, in create\r\n    model.save()\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 1513, in save\r\n    saved = self._perform_insert(query, options)\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 1584, in _perform_insert\r\n    self._insert_and_set_id(query, attributes)\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 1608, in _insert_and_set_id\r\n    self.set_attribute(key_name, id)\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 2507, in set_attribute\r\n    if self._has_set_mutator(key):\r\n  File \"/home/joel/anaconda2/lib/python2.7/site-packages/orator/orm/model.py\", line 2378, in _has_set_mutator\r\n    if key not in self._mutator_cache[klass]:\r\nTypeError: unhashable type: 'list'\r\n```\r\n\r\nThis is using the PyMySQL database adapter."}}