I have a user class, a contact class, and a googleID class.
the contact class has can have a googleID per user in the system. I'm
trying to map it out as follows:
# ArkContact - clientprojectshot module
orm.mapper(ArkContact, contacts_table, properties={
'notes': orm.relation(ArkNote,
secondary=contact_notes_table,
backref='contacts',
single_parent=True,
cascade="all, delete, delete-orphan"),
'users': orm.relation(ArkUser,
secondary=user_contact_table,
backref='contacts'),
'google_UID': orm.relation(ArkUserContactGUID,
cascade="all, delete",
backref='user')
})
#user contact google_GUID
user_contact_UID = sa.Table('user_contact_UID_table', meta.metadata,
sa.Column('user_id', sa.types.Integer, sa.ForeignKey('users.id'),
primary_key=True),
sa.Column('contact_id', sa.types.Integer,
sa.ForeignKey('contacts.id'), primary_key=True),
sa.Column('google_UID', sa.types.String(length = 1024))
)
class ArkUserContactGUID(object):
def __init__(self):
pass
orm.mapper(ArkUserContactGUID, user_contact_UID)
This raises two issues, the first is that an instrumented list is
returned for the google_UID paramter on the contact object, whereas
there should only ever be one (since as an operator there is only ever
one user signed in - you).
The second is it outright errors :), presumably because my mapping is off:
File 'C:\\ark\\ark\\controllers\\contacts.py', line 368 in initial_sync
contact_sync.initial_sync()
File 'C:\\ark\\ark\\arkTools\\arkGoogle.py', line 121 in initial_sync
self.add_contact_to_google(contact)
File 'C:\\ark\\ark\\arkTools\\arkGoogle.py', line 259 in add_contact_to_google
data.google_UID.append(entry.get_id())
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\collections.py',
line 952 in append
item = __set(self, item, _sa_initiator)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\collections.py',
line 927 in __set
item = getattr(executor, 'fire_append_event')(item, _sa_initiator)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\collections.py',
line 618 in fire_append_event
item, initiator)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\attributes.py',
line 741 in fire_append_event
value = fn(state, value, initiator or self)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\unitofwork.py',
line 35 in append
item_state = attributes.instance_state(item)
AttributeError: 'str' object has no attribute '_sa_instance_state'
Many thanks for any help!
Jules
For one-to-one relationships, you should supply "uselist=False" to your
relationship:
http://www.sqlalchemy.org/docs/orm/relationships.html#one-to-one
You're passing a string (presumably the result of entry.get_id()) where
SA is expecting an instance of a mapped class. I haven't looked at your
mapping in detail, but rather than this:
data.google_UID.append(entry.get_id())
you probably want something like this:
obj = ArkUserContactGUID(google_UID=entry.get_id())
data.google_UID.append(obj)
(If I've misunderstood your mapping, these class names are probably
wrong)
Hope that helps,
Simon
I'm now getting an SQL error, I think because the user is not being
pulled automatically through when trying to add the
ArkUserContactGUID:
OperationalError: (OperationalError) (1364, "Field 'user_id' doesn't
have a default value") 'INSERT INTO `user_contact_UID_table`
(contact_id, uid) VALUES (%s, %s)' (2L,
'http://www.google.com/m8/feeds/contacts/jules%40kettlestudio.co.uk/base/7c5456c108b2111b')
File 'C:\\ark\\ark\\controllers\\contacts.py', line 368 in initial_sync
contact_sync.initial_sync()
File 'C:\\ark\\ark\\arkTools\\arkGoogle.py', line 121 in initial_sync
self.add_contact_to_google(contact)
File 'C:\\ark\\ark\\arkTools\\arkGoogle.py', line 263 in add_contact_to_google
meta.Session.commit()
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\scoping.py',
line 113 in do
return getattr(self.registry(), name)(*args, **kwargs)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\session.py',
line 617 in commit
self.transaction.commit()
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\session.py',
line 293 in commit
self._prepare_impl()
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\session.py',
line 277 in _prepare_impl
self.session.flush()
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\session.py',
line 1473 in flush
self._flush(objects)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\session.py',
line 1542 in _flush
flush_context.execute()
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\unitofwork.py',
line 327 in execute
rec.execute(self)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\unitofwork.py',
line 471 in execute
uow
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\orm\\mapper.py',
line 2163 in _save_obj
execute(statement, params)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\engine\\base.py',
line 1358 in execute
params)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\engine\\base.py',
line 1491 in _execute_clauseelement
compiled_sql, distilled_params
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\engine\\base.py',
line 1599 in _execute_context
context)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\engine\\base.py',
line 1592 in _execute_context
context)
File 'C:\\ark\\env_x64\\lib\\site-packages\\sqlalchemy-0.7.1-py2.6.egg\\sqlalchemy\\engine\\default.py',
line 325 in do_execute
cursor.execute(statement, parameters)
File 'C:\\ark\\env_x64\\lib\\site-packages\\MySQLdb\\cursors.py', line
173 in execute
self.errorhandler(self, exc, value)
File 'C:\\ark\\env_x64\\lib\\site-packages\\MySQLdb\\connections.py',
line 36 in defaulterrorhandler
raise errorclass, errorvalue
OperationalError: (OperationalError) (1364, "Field 'user_id' doesn't
have a default value") 'INSERT INTO `user_contact_UID_table`
(contact_id, uid) VALUES (%s, %s)' (2L,
'http://www.google.com/m8/feeds/contacts/jules%40kettlestudio.co.uk/base/7c5456c108b2111b')
I think this is because the contacts object uses a many to many
relationship (a contact can belong to any or all users), code as
follows:
# ArkContact - clientprojectshot module
orm.mapper(ArkContact, contacts_table, properties={
'notes': orm.relation(ArkNote,
secondary=contact_notes_table,
backref='contacts',
single_parent=True,
cascade="all, delete, delete-orphan"),
'users': orm.relation(ArkUser,
secondary=user_contact_table,
backref='contacts'),
'google_UID': orm.relation(ArkUserContactGUID,
cascade="all, delete",
uselist=False,
backref='user')
})
I'm thinking I should join between the user and ArkUserContactGUID
somehow, but don't know how...
Many thanks,
Jules
> --
> You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
> To post to this group, send email to sqlal...@googlegroups.com.
> To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
>
>
Thanks again for the help, much appreciated.
Jules