name
sütununu polimorfik olarak tanımlayan Entity
numaralı bir bildirim sınıfım var.Polimorfik kimlik için SQLAlchemy sözdizimini geliştirin
class Entity(DeclarativeBase):
name = Column('name', String(40))
__mapper_args__ = {'polymorphic_on':name}
alt sınıfları, ben şimdi
class Experiment(Entity):
__mapper_args__ = {'polymorphic_identity': "experiment"}
söyleyebiliriz ve yapılması gereken. Ancak, benim kütüphanenin kullanıcıları için alt sınıflarının oluşturulmasını kolaylaştırmak ve bu nedenle yapmak istiyorum mümkün şunlardır:
- varsayılan sözdizimi kadar dolambaçlı değil onun için daha iyi sözdizimi var. Bu, sınıfın içinde veya belki de bir sınıf dekoratöründe
poly_id = "exp"
'un basit bir ataması olabilir. - Polimorfik bir kimlik belirtilmezse, adı alt sınıfın adından çıkarın.
ben bu işi metaclasses kullanarak (sadece ikinci bölümünü) almaya çalıştı: böylece
from sqlalchemy.ext.declarative import DeclarativeMeta
class Meta(type):
def __init__(cls, classname, bases, dict_):
dict_["__mapper_args__"] = {'polymorphic_identity': classname}
return super(Meta, cls).__init__(classname, bases, dict_)
class CombinedMeta(Meta, DeclarativeMeta):
pass
class Experiment(Entity):
__metaclass__ = CombinedMeta
, bence, benim Meta
DeclarativeMeta
çağırmadan önce adını ayarlamak gerekir ama o görünmüyor çalışmak. Yani ya polimorfik ismi belirlediği varsayılan DeclarativeMeta
, MRO'yu karıştırdığımdan ya da yaptığım şey zaten yanlış bir yanlıştır. SQLAlchemy'de neye benzer bir değişiklik yapmam gerekiyordu ya da böyle bir şey var mı?
'__init__' çağrıldığında, sınıf zaten oluşturulmuştur. __init__' bir kurucu değil. Eğer bunu __new__' içinde yaptıysanız, sorunsuz çalışırdı. Ve pek çok meta sınıfına sahip olmanıza gerek yok ... sadece sınıf MyMeta (DeclarativeMeta): ... 've sonra bildirimsel tablonuzu MyMeta'dan başlat. – Veky