2012-08-09 10 views
5

Supongamos que tengo las siguientes clases SQLAlchemy definido:¿Cómo puedo determinar el tipo (por ejemplo, muchos a uno) de una relación dinámica de SQLAlchemy?

Base = declarative_base() 

class Person(Base): 
    __tablename__ = 'person' 
    id = Column(Integer, primary_key=True) 
    computers = relationship('Computer', backref=backref('owner', lazy='dynamic')) 

class Computer(Base): 
    __tablename__ = 'computer' 
    id = Column(Integer, primary_key=True) 
    ownerid = Column(Integer, ForeignKey('person.id')) 

Supongamos, además, que he accedido al objeto de consulta perezoso de esta manera:

relation = getattr(Computer, 'owner') 

Cómo puedo determinar si relation se refiere a una sola instancia de Person (es decir, en una relación muchos a uno, como en este ejemplo), o si relation se refiere a una colección de instancias (como en una relación de uno a varios)? En otras palabras, ¿cómo puedo determinar el tipo de relación de un objeto de relación dinámico SQLAlchemy?

+0

No estoy seguro si entiendo bien la pregunta, pero con su ejemplo, ¿por qué no solo verifica si se trata de una colección (por ejemplo, una lista) o de un solo elemento? Esto es completamente independiente de SQLAlchemy y utilizaría por completo la función ORM de SQLAlchemy y el resumen de la base de datos. – javex

+0

En su mayoría tiene razón: creo que la solución correcta es comprobar si 'isinstance (relation, list)' --- si es verdadero, entonces podemos usarlo como una lista, pero si es falso, debe llamar a 'relation.one () 'para mapear la relación con una instancia concreta. Si agrega una respuesta a continuación, puedo recompensarlo (incorpore la advertencia que he establecido aquí, si puede). – argentpepper

Respuesta

2

Si suponemos model = Computer y relation = 'owner' como en la pregunta, entonces el atributo siguiente es True si y sólo si la relación es una lista de las veces en contraposición a una sola instancia:

model._sa_class_manager[relation].property.uselist 

A continuación, puede utilizar esto para probar si o no para llamar al método one() en el resultado de getattr(model, relation):

if model._sa_class_manager[relation].property.uselist: 
    related_instances = getattr(model, relation) 
else: 
    related_instance = getattr(model, relation).one() 

no obstante estoy seguro, que esta es la mejor solución.

Cuestiones relacionadas