Форум сайта python.su
class Model1(db.Model):
ref = db.ReferenceProperty(required=True, reference_class=Model3)
ref = db.ReferenceProperty(required=True, reference_class=Model2)
class Model2(db.Model):
ref = db.ReferenceProperty(required=True, reference_class=Model3)
ref = db.ReferenceProperty(required=True, reference_class=Model1)
class Model3(db.Model):
ref = db.ReferenceProperty(required=True, reference_class=Model1)
ref = db.ReferenceProperty(required=True, reference_class=Model2)
Офлайн
А так не подойдет?
class Model1(db.Model):
pass
class Model2(db.Model):
pass
class Model3(db.Model):
pass
ref = db.ReferenceProperty(required=True, reference_class=Model3)
Model1.ref = db.ReferenceProperty(required=True, reference_class=Model1)
ref = db.ReferenceProperty(required=True, reference_class=Model3)
Model2.ref = db.ReferenceProperty(required=True, reference_class=Model2)
ref = db.ReferenceProperty(required=True, reference_class=Model1)
Model3.ref = db.ReferenceProperty(required=True, reference_class=Model2)
del ref
Офлайн
hzkto1Вообще с большой долей вероятности Вы хотите странного. Поэтому опишите конкретней вашу задачу, возможно удастся найти ее решение малой кровью
Подскажите как решить такую ситуацию, не думал что на питоне классы инициализируется построчно. Есть какие нибудь способы обойти это ограничение, желательно как можно менее костыльные. PS код пишется под Google App Engine.
Офлайн
Извиняюсь в первом примере я использовал одно и тоже имя переменной - ref, поэтому меня не правильно поняли, сейчас распишу подробнее.
Есть файл database там должны быть описаны все модели datastore, дело в том что многие таблицы линкуются. В Google App Engine datastore для этого используется такой синтаксис как я привел выше. И получается ситуация когда я немогу расположить классы в таком порядке чтобы классы инициализировались попорядку, что самое интересное я могу создать экземляр класса в методе класса который находится выше, чем создаваемый класс. А вот использовать рефенс класса не могу.
Вот черновой оригинал файла с моделями таблиц:
#!/usr/bin/env python
from google.appengine.ext import db
class Battle(db.Model):
id = db.StringProperty()
date = db.DateTimeProperty()
trainer1 = db.ReferenceProperty(reference_class=Trainer)
trainer2 = db.ReferenceProperty(reference_class=Trainer)
pokemon1 = db.ReferenceProperty(reference_class=Pokemon)
pokemon2 = db.ReferenceProperty(reference_class=Pokemon)
class BattleAction(db.Model):
battle = db.ReferenceProperty(required=True, reference_class=Battle)
step = db.IntegerProperty(required=True, default=1)
start_time = db.TimeProperty(required=True)
action_time = db.TimeProperty(required=True)
active_trainer = db.ReferenceProperty(required=True, reference_class=Trainer)
action_id = db.IntegerProperty(required=True)
class Pokemon(db.Model):
id = db.IntegerProperty(required=True)
trainer = db.IntegerProperty(required=True)
type = db.ListProperty(required=True)
form = db.ListProperty(required=True)
property = db.ListProperty(required=True)
pattern = db.IntegerProperty(required=True)
stats = db.ReferenceProperty(required=True, reference_class=PokemonStats)
effort_stats = db.ReferenceProperty(required=True, reference_class=PokemonStats)
iv_stats = db.ReferenceProperty(required=True, reference_class=PokemonStats)
ev_stats = db.ReferenceProperty(required=True, reference_class=PokemonStats)
class PokemonStats(db.Model):
hp = db.IntegerProperty(required=True)
attack = db.IntegerProperty(required=True)
defence = db.IntegerProperty(required=True)
special_attack = db.IntegerProperty(required=True)
special_defence = db.IntegerProperty(required=True)
speed = db.IntegerProperty(required=True)
class pokemon_attack(db.Model):
id = db.IntegerProperty()
type = db.IntegerProperty()
power = db.IntegerProperty()
accuracy = db.IntegerProperty()
mana = db.IntegerProperty()
class Trainer(db.Model):
id = db.StringProperty(required=True)
name = db.StringProperty(required=True)
online = db.BooleanProperty(required=True, default=False)
last_activity = db.DateTimeProperty(required=True)
channel_id = db.StringProperty()
Отредактировано (Фев. 7, 2012 22:52:14)
Офлайн
В данном случае достаточно изменить порядок описания классов на следующий:
PokemonStats
pokemon_attack
Trainer
Pokemon
Battle
BattleAction
Офлайн
Ну это пока еще не полная модель, есть все таки какое-то решение этой ситуации или это данность языка которую не обойти? Все таки не хотелось бы в проектировании базы отталкиваться от данного ограничения.
Офлайн
Атрибут к классу можно добавить и потом. А вообще, циклических ссылок при проектировании нужно избегать.
Офлайн
Я решил использовать не ссылочные поля а строковые, генерировать уникальные id каждой строке в таблицах, и связывать таблицы таким образом. Думаю что это решит эту проблему. Таким путем я не приду в тупик?
#!/usr/bin/env python
from google.appengine.ext import db
class Battle(db.Model):
id = db.StringProperty() #uuid
date = db.DateTimeProperty()
trainer1 = db.StringProperty()
trainer2 = db.StringProperty()
pokemon1 = db.StringProperty()
pokemon2 = db.StringProperty()
class BattleAction(db.Model):
battle_id = db.StringProperty() # many(this) to one(battle)
step = db.IntegerProperty(default=1)
start_time = db.TimeProperty()
action_time = db.TimeProperty()
active_trainer = db.StringProperty()
action_id = db.IntegerProperty()
class Pokemon(db.Model):
id = db.StringProperty() #uuid
trainer_id = db.StringProperty() #many(this) to one(trainer)
type = db.StringProperty() #json
form = db.StringProperty() #json
property = db.StringProperty() #json
pattern = db.IntegerProperty()
stats = db.StringProperty() #one(this) to one(pokemonstatset)
effort_stats = db.StringProperty() #one(this) to one(pokemonstatset)
iv_stats = db.StringProperty() #one(this) to one(pokemonstatset)
ev_stats = db.StringProperty() #one(this) to one(pokemonstatset)
class PokemonStatSet(db.Model):
id = db.StringProperty() #uuid
hp = db.IntegerProperty()
attack = db.IntegerProperty()
defence = db.IntegerProperty()
special_attack = db.IntegerProperty()
special_defence = db.IntegerProperty()
speed = db.IntegerProperty()
class PokemonAttack(db.Model):
id = db.IntegerProperty()
type = db.IntegerProperty()
power = db.IntegerProperty()
accuracy = db.IntegerProperty()
mana = db.IntegerProperty()
class Trainer(db.Model):
id = db.StringProperty() #uuid
name = db.StringProperty()
online = db.BooleanProperty(default=False)
last_activity = db.DateTimeProperty()
channel_id = db.StringProperty()
Офлайн
hzkto1, извращение. Как Вам уже объяснили циклических ссылок необходимо избегать. Единственный случай, когда проблематично сделать ссылку из-за особенности питона - это ссылка на себя. Но тут у GAE предусмотрен класс SelfReferencePropery. Во всех остальных случаях проектируйте так, чтобы не изобретать различного рода извращения.
P.S. И вообще разберитесь как устроены модели в Google App Engine. Ваша идея с uuid есть ничто иное как изобретение велосипеда, ибо key и так представляет собой уникальный идентификатор любой сущности в хранилище. (На этом этапе должно возникнуть острое желание почитать справочное руководство). А дальше стоит начать думать как сделать модель нормально, чтобы избежать лютых “ссылок на ссылку и ссылками погоняет” и необходимости изобретать странные решения.
Отредактировано (Фев. 8, 2012 20:54:26)
Офлайн
Спасибо, досконально изучил справку, провел некоторые эксперименты свои ошибки понял)
Офлайн