Sto provando a creare una struttura di database in cui sono presenti molti tipi di entità di contenuto, di cui una, un commento, può essere associata a qualsiasi altra.Creazione di tabelle autoreferenziali con polimorfismo in SQLALchemy
Si consideri il seguente:
from datetime import datetime
from sqlalchemy import create_engine
from sqlalchemy import Column, ForeignKey
from sqlalchemy import Unicode, Integer, DateTime
from sqlalchemy.orm import relation, backref
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Entity(Base):
__tablename__ = 'entities'
id = Column(Integer, primary_key=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
edited_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
type = Column(Unicode(20), nullable=False)
__mapper_args__ = {'polymorphic_on': type}
# <...insert some models based on Entity...>
class Comment(Entity):
__tablename__ = 'comments'
__mapper_args__ = {'polymorphic_identity': u'comment'}
id = Column(None, ForeignKey('entities.id'), primary_key=True)
_idref = relation(Entity, foreign_keys=id, primaryjoin=id == Entity.id)
attached_to_id = Column(Integer, ForeignKey('entities.id'), nullable=False)
#attached_to = relation(Entity, remote_side=[Entity.id])
attached_to = relation(Entity, foreign_keys=attached_to_id,
primaryjoin=attached_to_id == Entity.id,
backref=backref('comments', cascade="all, delete-orphan"))
text = Column(Unicode(255), nullable=False)
engine = create_engine('sqlite://', echo=True)
Base.metadata.bind = engine
Base.metadata.create_all(engine)
Questo sembra circa la destra, ad eccezione SQLAlchemy non piace avere due chiavi esterne che puntano allo stesso genitore. Dice ArgumentError: Can't determine join between 'entities' and 'comments'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly.
Come specificare onclause
?
L'_idref è stato un tentativo di chiarire a SQLAlchemy quale relazione si riferisce a cosa. È inutile nel mio codice. –
Quindi ho appena provato questo ed è stato corretto il problema, ma ne ho introdotto uno nuovo: eliminare qualsiasi altra entità (che ha un backref da questo modello, ma nessuna istanza) fallisce con 'TypeError: id() richiede esattamente un argomento (0 dato) ' –
Non ho capito completamente il tuo commento ma sembra che tu abbia problemi con la funzione' id() 'di Python. Hai dimenticato di anteporre id con 'self'? O hai spostato '__mapper_args__' nella dichiarazione di classe * dopo la * dichiarazione del campo' id'? – nkrkv