Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 7, 2012 16:11:03

hzkto1
От:
Зарегистрирован: 2010-11-08
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Построчная инициализация классов

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.



Офлайн

#2 Фев. 7, 2012 20:17:26

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Построчная инициализация классов

А так не подойдет?

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



Офлайн

#3 Фев. 7, 2012 22:07:44

cutwater
От:
Зарегистрирован: 2009-01-08
Сообщения: 444
Репутация: +  19  -
Профиль   Отправить e-mail  

Построчная инициализация классов

hzkto1
Подскажите как решить такую ситуацию, не думал что на питоне классы инициализируется построчно. Есть какие нибудь способы обойти это ограничение, желательно как можно менее костыльные. PS код пишется под Google App Engine.
Вообще с большой долей вероятности Вы хотите странного. Поэтому опишите конкретней вашу задачу, возможно удастся найти ее решение малой кровью



Офлайн

#4 Фев. 7, 2012 22:45:51

hzkto1
От:
Зарегистрирован: 2010-11-08
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Построчная инициализация классов

Извиняюсь в первом примере я использовал одно и тоже имя переменной - 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)

Офлайн

#5 Фев. 8, 2012 07:26:22

agalen
От:
Зарегистрирован: 2011-03-23
Сообщения: 185
Репутация: +  17  -
Профиль   Отправить e-mail  

Построчная инициализация классов

В данном случае достаточно изменить порядок описания классов на следующий:
PokemonStats
pokemon_attack
Trainer
Pokemon
Battle
BattleAction



Офлайн

#6 Фев. 8, 2012 07:50:59

hzkto1
От:
Зарегистрирован: 2010-11-08
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Построчная инициализация классов

Ну это пока еще не полная модель, есть все таки какое-то решение этой ситуации или это данность языка которую не обойти? Все таки не хотелось бы в проектировании базы отталкиваться от данного ограничения.



Офлайн

#7 Фев. 8, 2012 09:04:42

agalen
От:
Зарегистрирован: 2011-03-23
Сообщения: 185
Репутация: +  17  -
Профиль   Отправить e-mail  

Построчная инициализация классов

Атрибут к классу можно добавить и потом. А вообще, циклических ссылок при проектировании нужно избегать.



Офлайн

#8 Фев. 8, 2012 09:52:04

hzkto1
От:
Зарегистрирован: 2010-11-08
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Построчная инициализация классов

Я решил использовать не ссылочные поля а строковые, генерировать уникальные 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()
Что скажете о таком моделировании?



Офлайн

#9 Фев. 8, 2012 18:45:15

cutwater
От:
Зарегистрирован: 2009-01-08
Сообщения: 444
Репутация: +  19  -
Профиль   Отправить e-mail  

Построчная инициализация классов

hzkto1, извращение. Как Вам уже объяснили циклических ссылок необходимо избегать. Единственный случай, когда проблематично сделать ссылку из-за особенности питона - это ссылка на себя. Но тут у GAE предусмотрен класс SelfReferencePropery. Во всех остальных случаях проектируйте так, чтобы не изобретать различного рода извращения.

P.S. И вообще разберитесь как устроены модели в Google App Engine. Ваша идея с uuid есть ничто иное как изобретение велосипеда, ибо key и так представляет собой уникальный идентификатор любой сущности в хранилище. (На этом этапе должно возникнуть острое желание почитать справочное руководство). А дальше стоит начать думать как сделать модель нормально, чтобы избежать лютых “ссылок на ссылку и ссылками погоняет” и необходимости изобретать странные решения.



Отредактировано (Фев. 8, 2012 20:54:26)

Офлайн

#10 Фев. 11, 2012 21:21:11

hzkto1
От:
Зарегистрирован: 2010-11-08
Сообщения: 15
Репутация: +  0  -
Профиль   Отправить e-mail  

Построчная инициализация классов

Спасибо, досконально изучил справку, провел некоторые эксперименты свои ошибки понял)



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version