pony
pony copied to clipboard
MappingError: Different column names should be specified for attributes User.followers and User.followers
I'm currently trying to do a followers/following twitter set up. I thought I just needed to do a self refrence but seems with postgres I am getting a error
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/gunicorn/arbiter.py", line 473, in spawn_worker
worker.init_process()
File "/usr/lib/python2.7/dist-packages/gunicorn/workers/base.py", line 100, in init_process
self.wsgi = self.app.wsgi()
File "/usr/lib/python2.7/dist-packages/gunicorn/app/base.py", line 115, in wsgi
self.callable = self.load()
File "/usr/lib/python2.7/dist-packages/gunicorn/app/wsgiapp.py", line 33, in load
return util.import_app(self.app_uri)
File "/usr/lib/python2.7/dist-packages/gunicorn/util.py", line 362, in import_app
__import__(module)
File "/home/www/youtstream/app.py", line 20, in <module>
from models import User, Video
File "/home/www/youtstream/models.py", line 68, in <module>
db.generate_mapping(create_tables=True)
File "<auto generated wrapper of generate_mapping() function>", line 2, in generate_mapping
File "/usr/local/lib/python2.7/dist-packages/pony/utils.py", line 65, in cut_traceback
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/pony/orm/core.py", line 770, in generate_mapping
'Different column names should be specified for attributes %s and %s' % (attr, reverse))
File "/usr/local/lib/python2.7/dist-packages/pony/utils.py", line 103, in throw
raise exc
MappingError: Different column names should be specified for attributes User.followers and User.followers
This is what I currently have as the model
class User(db.Entity):
id = PrimaryKey(int, auto=True)
photo_url = Optional(unicode)
username = Required(unicode, 20, unique=True)
name = Optional(unicode, 255)
email = Required(unicode, 255, unique=True)
password_hash = Optional(unicode, 255)
videos = Set(lambda: Video)
verified = Required(bool, default=False)
premium = Required(bool, default=False)
followers = Set(lambda: User, reverse="followers")
bio = Optional(unicode, 255)
gifs = Set(lambda: Gif)
newsletter = Optional(unicode, 255)
created_at = Required(datetime, default=datetime.now())
def hash_password(self, password):
self.password_hash = pwd_context.encrypt(password)
def verify_password(self, password):
return pwd_context.verify(password, self.password_hash)
def generate_auth_token(self):
s = Serializer(current_app.config['SECRET_KEY'])
return s.dumps({ 'id': self.id })
def generate_auth_email_token(self):
s = Serializer(current_app.config['SECRET_KEY'], expires_in = 60 * 60 * 24)
return s.dumps({ 'id': self.id })
@staticmethod
def verify_auth_token(token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
data = s.loads(token)
except SignatureExpired:
return None # valid token, but expired
except BadSignature:
return None # invalid token
if not data['id']:
return None
user = User[data['id']]
return user
class Video(db.Entity):
video_id = Required(unicode)
users = Set(lambda: User)
class Gif(db.Entity):
name = Required(unicode)
gif_id = Required(unicode)
users = Set(lambda: User)
sql_debug(True)
db.generate_mapping(create_tables=True)
Thanks for the reporting, this is a bug. As a workaround, please replace the line
followers = Set(lambda: User, reverse="followers")
with the next line:
followers = Set("User", reverse="followers")
As a side note, I'm not sure that followers attribute should be defined as specified. When the attribute is specified as a reverse attribute to itself, this means that the attribute is symmetrical, that is, when you add John as a follower to Mike, Mike becomes follower of John automatically. But probably this is not what you want. It is more traditional to define following relation in the next way:
class User(db.Entity):
...
followers = Set(lambda: User, reverse='followee')
followee = Set(lambda: User, reverse='followers')
This way it will be possible to user to not follow its followers.
Thank you, I ended up doing the followee and followers, but i suppose glad I found a bug in the process.
Sorry for updating this ancient issue! But where is the bug exactly? It seems to work as intended, has it gotten fixed?