Найти - Пользователи
Полная версия: Построчная инициализация классов
Начало » Python для новичков » Построчная инициализация классов
1
hzkto1
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)
Подскажите как решить такую ситуацию, не думал что на питоне классы инициализируется построчно. Есть какие нибудь способы обойти это ограничение, желательно как можно менее костыльные. PS код пишется под Google App Engine.
doza_and
А так не подойдет?
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
cutwater
hzkto1
Подскажите как решить такую ситуацию, не думал что на питоне классы инициализируется построчно. Есть какие нибудь способы обойти это ограничение, желательно как можно менее костыльные. PS код пишется под Google App Engine.
Вообще с большой долей вероятности Вы хотите странного. Поэтому опишите конкретней вашу задачу, возможно удастся найти ее решение малой кровью
hzkto1
Извиняюсь в первом примере я использовал одно и тоже имя переменной - 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()
agalen
В данном случае достаточно изменить порядок описания классов на следующий:
PokemonStats
pokemon_attack
Trainer
Pokemon
Battle
BattleAction
hzkto1
Ну это пока еще не полная модель, есть все таки какое-то решение этой ситуации или это данность языка которую не обойти? Все таки не хотелось бы в проектировании базы отталкиваться от данного ограничения.
agalen
Атрибут к классу можно добавить и потом. А вообще, циклических ссылок при проектировании нужно избегать.
hzkto1
Я решил использовать не ссылочные поля а строковые, генерировать уникальные 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()
Что скажете о таком моделировании?
cutwater
hzkto1, извращение. Как Вам уже объяснили циклических ссылок необходимо избегать. Единственный случай, когда проблематично сделать ссылку из-за особенности питона - это ссылка на себя. Но тут у GAE предусмотрен класс SelfReferencePropery. Во всех остальных случаях проектируйте так, чтобы не изобретать различного рода извращения.

P.S. И вообще разберитесь как устроены модели в Google App Engine. Ваша идея с uuid есть ничто иное как изобретение велосипеда, ибо key и так представляет собой уникальный идентификатор любой сущности в хранилище. (На этом этапе должно возникнуть острое желание почитать справочное руководство). А дальше стоит начать думать как сделать модель нормально, чтобы избежать лютых “ссылок на ссылку и ссылками погоняет” и необходимости изобретать странные решения.
hzkto1
Спасибо, досконально изучил справку, провел некоторые эксперименты свои ошибки понял)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB