TurboGears / tg2

Python web framework with full-stack layer implemented on top of a microframework core with support for SQL DBMS, MongoDB and Pluggable Applications
http://www.turbogears.org/
Other
806 stars 78 forks source link

AttributeError: 'function' object has no attribute 'primary_key' #64

Closed 984958198 closed 9 years ago

984958198 commented 9 years ago

File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\wsgiapp.py", line 105, in call response = self.wrapped_dispatch(controller, environ, context) File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\wsgiapp.py", line 278, in dispatch return controller(environ, context) File "e:\for_guozhixing\dqwebsvr\dqwebsvr\lib\base.py", line 30, in call return TGController.call(self, environ, context) File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\controllers\dispatcher.py", line 132, in call response = self._perform_call(context) File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\controllers\dispatcher.py", line 105, in _perform_call state, params = self._get_dispatchable(context, py_request.quoted_path_info) File "D:\Python27\Scripts\tgenv\lib\site-packages\tg\controllers\dispatcher.py", line 75, in _get_dispatchable state = state.controller._dispatch(state, url_path) File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 188, in _dispatch state, current_args) File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 106, in _dispatch_controller return dispatcher(state, remainder) File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 191, in _dispatch return self._dispatch_first_found_default_or_lookup(state, remainder) File "D:\Python27\Scripts\tgenv\lib\site-packages\crank\objectdispatcher.py", line 132, in _dispatch_first_found_default_or_lookup new_controller, new_remainder = meth(*m_remainder) File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\controller.py", line 133, in _lookup controller = self.controllers_cache[model_name] = self._make_controller(config, self.session) File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\controller.py", line 91, in _make_controller class ModelController(Controller): File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\controller.py", line 95, in ModelController new_form = config.new_form_type(session) File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\configbase.py", line 76, in init self._do_init_attrs() File "D:\Python27\Scripts\tgenv\lib\site-packages\tgext\admin\widgets.py", line 94, in _do_init_attrs super(BootstrapAdminAddRecordForm, self)._do_init_attrs() File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\formbase.py", line 471, in _do_init_attrs pkey = self.provider.get_primary_field(self.entity) File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\sa\provider.py", line 170, in get_primary_field fields = self.get_primary_fields(entity) File "D:\Python27\Scripts\tgenv\lib\site-packages\sprox-0.9.5-py2.7.egg\sprox\sa\provider.py", line 165, in get_primary_fields if value.primary_key and not field_name in fields: AttributeError: 'function' object has no attribute 'primary_key'

class TaskMessage(DeclarativeBase): tablename = 'task_message' table_args = {'mysql_charset': 'utf8', 'mysql_engine': 'InnoDB'} id = Column(BigInteger, Sequence('task_message_id_seq'), primary_key=True) create_time = Column(DateTime, default=datetime.now) update_time = Column(TIMESTAMP, default=datetime.now, onupdate=func.current_timestamp())

user_id = Column(Integer, ForeignKey('sys_user.user_id'), nullable=False)
title = Column(Unicode(255), nullable=False)
status = Column(SmallInteger, default=1,doc=u'1:进行中,2:中断,3:完成,4:删除')
is_read = Column(SmallInteger, default=0,doc=u'0:未读完,1:已读完')
task_name = Column(Unicode(63),doc=u'线程名 主要用于取消任务')

class TaskMessageItem(DeclarativeBase): tablename = 'task_message_item' table_args = {'mysql_charset': 'utf8', 'mysql_engine': 'InnoDB'} id = Column(BigInteger, Sequence('task_message_item_id_seq'), primary_key=True) create_time = Column(DateTime, default=datetime.now) update_time = Column(TIMESTAMP, default=datetime.now, onupdate=func.current_timestamp())

task_message_id = Column(BigInteger,ForeignKey('task_message.id'),nullable=False)
msg = Column(Text, nullable=False)
is_read = Column(SmallInteger, default=0,doc=u'0:未读,1:已读')

task_messages = relation(TaskMessage, backref='items')
amol- commented 9 years ago

Interesting, you found actually a really curious corner case in SQLAlchemy...

The OrderedProperties of a mapper mimics the behaviour of a dictionary, and so it has an items() method like dictionaries. As you named the backref of your relation items SQLAlchemy makes it available in the OrderedProperties but when you try to access it you actually get back the items method of the dictionary instead of getting back the backref.

That is making sprox crash as methods do not provide the expected primary_key property.

amol- commented 9 years ago

Please upgrade Sprox to 0.9.6, that should solve your issue.