2017-01-29 13 views
8

ゲームエンジンは、uniqueidプレイヤーを識別するための読み取り専用プロパティを持つPlayerクラスを提供します。私は選手たちを照会できるように、このようにそれをSQLAlchemyののColumnにこれを「変換」したいと思います:同じ値を持つ読み取り専用列で読み取り専用プロパティをオーバーライドします。

class Player(game.Player, db.Model): 
    _uniqueid = Column('uniqueid', String(21), unique=True, nullable=False) 

    def __init__(self, index, **kwargs): 
     game.Player.__init__(index) # initializes uniqueid 
     db.Model.__init__(_uniqueid=self.uniqueid, **kwargs) 

次は私がしたい:

query = session.query(Player).filter(Player.uniqueid=='STEAM_0:0:1234567') 
player = query.one_or_none() 
if player is None: 
    player = Player(uniqueid='STEAM_0:0:1234567') 

はここに私のクラスは現在、次のようになります。 _uniqueidの読み取り専用インターフェイスを作成すると、APIユーザーは変数に書き込むことができなくなります(_uniqueidでアクセスできますが、アクセスは個人的でないuniqueidを通じて行われるため、責任があります)。

は、私は新しいもので、元のuniqueidを上書きを考える:

​​

これは、彼らが意図的に民間のいずれかにアクセスしない限り、それへの書き込みから誰を防ぐ「皮革」オリジナル_uniqueid、読み取り専用します(私はドキュメンテーションにもそれを載せません。非公開のものだけを公開します)。

唯一の問題は完全にこのが私の__init___uniqueid=self.uniqueid新しいゲッターではなく、古いものを使用して原因self.uniqueidに動作しないことを意味し、古いものを上書きしますということです。

私が望むのは、読み取り専用のプロパティをSQLAlchemyでクエリに使用できる読み取り専用のものに変換することです。これは可能ですか?

+0

これは、 'game.Player.uniqueid'がどのように実装されているかによって異なります。それはインスタンス辞書に何を入れますか?データベースから 'Player'インスタンスを再水和する必要があるときに、どのように値を設定しますか?これは第三者図書館の理由を考えるのが難しいかもしれないので、私は一般にモデルクラスとこのような第三者のクラスを混ぜることはお勧めしません。 – univerio

+0

@univerioこれはちょっとしたCの魔法を使う読み込み専用の 'property'です。基本的に 'player_join'イベントが発生すると、ゲームエンジンは参加しているプレーヤーの' index'を提供し、 'player = game.Player(index)'を実行すると、 。 –

+0

しかし、 'uniqueid'の実際のデータはどこに保存されていますか?あなたはそれが 'index'から計算されていると言っていますか?そして、あなたは「プレーヤー」を再水和するために必要なのはその指標ですか? – univerio

答えて

1

superを使用すると、game.Playerのプロパティにアクセスできます。私たちは、Cythonで作成した簡単なCの拡張タイプを使用してテストすることができます。

# game.pyx 
cdef class Player: 
    cdef int index; 

    def __init__(self, index): 
     self.index = index 

    @property 
    def uniqueid(self): 
     return "foo" 


# test.py 
class Player(game.Player, Base): 
    __tablename__ = "player" 

    id = Column(Integer, primary_key=True) 
    _uniqueid = Column('uniqueid', String(21), unique=True, nullable=False) 

    def __init__(self, index, **kwargs): 
     game.Player.__init__(self, index) # initializes uniqueid 
     Base.__init__(self, _uniqueid=super().uniqueid, **kwargs) 

    @property 
    def uniqueid(self): 
     return self._uniqueid 

print(Player(1).uniqueid) # "foo" 

をため、Cの拡張型から継承するのprecariousnessの、これはあるいはgame.Playerタイプは使用しています正確に何Cの魔法によっては動作しない場合があります。

また、データベースからインスタンスをロードするときにORMが__init__をバイパスするため、game.Playerタイプを初期化するには、loadイベントにフックする必要があります。

+0

申し訳ありませんが、私は完全にこの質問を忘れてしまったようです...受け入れられupvoted今、これは確かに* does *働いています。 –

関連する問題