2016-07-28 59 views
6

bir oyun motoru steamid özelliğe sahip bir Player sınıf ile bana sağladığı (C++ gelen, işte bu Python nasılolabileceği üzerinde sadece temel bir örneğidir) bir gold özellik eklerken:Temel sınıfın özelliğini/özelliğini bir tablo sütunu olarak kullan?</p> <p>Sonra bu sınıfı alt sınıfı geçin:

# my_plugin.py 

class MyPlayer(game_engine.Player, Base): 
    gold = Column(Integer) 

Şimdi depolamak için gereken oyuncunun gold oyuncunun steamid oyuncu tanımlamak için birincil anahtar olarak bir veritabanına. SQLAlchemy 'i ana sınıfın steamid özelliğini birincil anahtar olarak kullanmasını nasıl söyleyebilirim? İşte

saçma şey denedim var:

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.ext.hybrid import hybrid_property 

import game_engine 

Base = declarative_base() 

class Player(game_engine.Player, Base): 
    __tablename__ = 'player' 

    _steamid = game_engine.Player.steamid 

    @hybrid_property 
    def steamid(self): 
     return type(self)._steamid.__get__(self) 

Ama evet, budur classical mapping

from sqlalchemy import Column, Integer, Table 
from sqlalchemy.orm import mapper 
from sqlalchemy.ext.hybrid import hybrid_property 


class MyPlayer(Player): 
    def __init__(self, steamid, gold): 
     super().__init__(steamid) 
     self.gold = gold 
     self._steamid = super().steamid 


player = Table('player', Base.metadata, 
    Column('_steamid', Integer, primary_key=True), 
    Column('gold', Integer), 
) 


mapper(MyPlayer, player) 

cevap

2

kullanarak bu yapılabilir

sqlalchemy.exc.ArgumentError: Mapper Mapper|Player|player could not assemble any primary key columns for mapped table 'player' 
+0

Bu çözümün bunu yapmak için "uygun" bir yol olduğunu hissediyorum, bu yüzden kabul ettim, ama ben * kişisel olarak * r-m-n'nin cevabını kullanarak bitireceğim, bu yüzden ona +100 rep vermek gibi hissettim. Umarım bu, SO'nun yönergelerine göre ... –

+0

Kılavuzlarda% 100 açık değilim, ama bu sizin ödülünüzü, böylece istediğiniz şekilde harcayabiliyorsunuz. En önemlisi, ödülün hepsini ödüllendirmek ve sen yaptın. Kabul için hala minnettarım. – Julian

+0

İkinci düşüncede, neden r-m-n'nin çözümünü kullanmayı umduğunuzu açıklayabilir misiniz? Bana göre, kendini cezalandırma gibi görünüyor ... – Julian

1

bir ihtimal ... oldu beklediğinizden daha basit. Aşağıdaki çözüm, r-m-n'den birine eşdeğerdir, ancak daha açıklayıcıdır çünkü modern deklaratif haritalama kullanır. @hybrid_property'a gerek yoktur, üst sınıftan sadece steamid'u kaldırabilirsiniz.

# my_plugin.py 

class MyPlayer(game_engine.Player, Base): 

    def __init__(self, steamid, gold): 
     super().__init__(steamid) 
     self._id = self.steamid 
     self.gold = gold 

    _id = Column('steamid', Integer, primary_key=True) 
    gold = Column(Integer) 
+1

Bu, ancak gerekli olandan daha karmaşıktır. Aynı sonucu bir bildirim eşleştirmesiyle ve '@ hybrid_property' kullanmadan da alabilirsiniz; cevabımı gör. – Julian

+0

Görünüşe göre yanılıyordum ve süper(). Steamid aslında * çalışıyor * (sadece ayarlayıcılar için değil), bu yüzden sadece "self._steamid = super(). Steamid" ten kurtulmak ve 'def Steamid (self): süper() olarak "hybrid_property" olarak "steamid" döndürün! Aynı zamanda klasik eşlemeyi * sonlandıracağım * çok fazla olmayan koddan dolayı * neyse cevap için teşekkürler! :) Ben, diğer cevap gibi hissettiğimden beri seninkileri kabul etmedim çünküJulian bunu yapmanın daha "uygun" yoluydu, ama seninkine bu kez yardım ettin, böylece sana 100 dolarlık ödül verdim. –

+0

İkinci bakışta, bu cevapta 'hybrid_property' kullanılmıyor gibi görünüyor. Bu bir hata mıydı? –