0

I'm trying to create tables with foreign keys in database with peewee.
Player table has ForeignKey to Team table and Team table has ForeignKey to Player table. When i run my code i'm getting NameError: name 'Team' is not defined
Here is my code:

class Player(Model):
    nickname = CharField(max_length=30)
    steam_id = CharField(max_length=15)
    team = ForeignKeyField(Team)
    class Meta:
        database = db

class Team(Model):
    name = CharField(max_length=30)
    captain = ForeignKeyField(Player)
    class Meta:
        database = db
Player.create_table()
Team.create_table()

Can someone help me? :)

KsaneK
  • 125
  • 1
  • 1
  • 5
  • I don't know peewee ònly SQL but you can't set a FK to a "class" / table that doesn't exists in SQL. I think here it's the same. You could try to add the FK after creation of both classes. Beside of this you could do a class `TeamPlayer` where you got 3 attributes: Player, Team and captain. So you avoid the crossing FKs – bish Jan 16 '15 at 15:21
  • Thanks for your fast answer! `setattr(Team, "captain", ForeignKeyField(Player))`, `setattr(Player, "team", ForeignKeyField(Team))` fixed the problem :) – KsaneK Jan 16 '15 at 15:32
  • This approach is actually not going to work well because of certain hooks that run during metaclass / model class creation. If you want to add a field dynamically instead you should call "field.add_to_class(model_class, field_name)". This will take care of setting the attribute correctly and running the hooks. *The best / correct answer*, however, is listed below in the answers section. – coleifer Jan 16 '15 at 19:30

2 Answers2

0

You're getting this error because you are referencing Team in Player, before you have defined Team. You have a circular dependency here. Team is dependent on Player and Player is dependent on Team.

My first suggestion would be to drop one of the dependencies. Do you really need a reference to the other in both tables?

If you do, then the peewee docs has an entire section dedicated to handling this situation: http://peewee.readthedocs.org/en/latest/peewee/models.html#circular-foreign-key-dependencies

dursk
  • 4,435
  • 2
  • 19
  • 30
0

You need to use DeferredForeignKey this uses the Django style type-as-string approach, but comes with the caveat it won't create your database constraints for you

So for

team = ForeignKeyField(Team)

use

team = DeferredForeignKeyField('Team')

and then later

db.create_tables([Player,Team])
Player._schema.create_foreign_key(Player.team)
Shayne
  • 1,571
  • 1
  • 16
  • 20