2011-10-17 21 views
9

Soy nuevo en sqlalchemy. Intentando que una consulta funcione y tengo problemas con una unión.Error de SQLAlchemy: "Configure explícitamente uno o más atributos para estas columnas con el mismo nombre".

Tengo dos tablas, ambas tienen una columna llamada "Id" y necesito unirme a esa tabla. Mi código es el siguiente:

table1 = server.tab1 
table2 = server.tab2 
joined = server.join(table1,table2, table1.Id == table2.Id) 
where = table1.createDate > start 
results = joined.filter(where).all() 

Implícitamente combinando table1.Id columna con la columna table2.Id bajo el atributo 'Id'. Configure uno o más atributos para estas columnas con el mismo nombre explícitamente.

La pregunta es, ¿cómo configuro estos atributos?

TIA!

Respuesta

-2

Puede utilizar unirse a las prestaciones proporcionadas por sqlalchemy, ver el siguiente ejemplo, no hay necesidad de hacerlo manualmente sqlalchme lo hace por nosotros,

from sqlalchemy import create_engine, Column, String, Integer, Table, ForeignKey 

from sqlalchemy.orm import mapper, relationship 
from sqlalchemy.schema import MetaData 
from sqlalchemy.orm.session import sessionmaker 

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 

class User(Base): 
    __tablename__ = 'users' 

    id = Column('user_id',Integer,primary_key = True) 
    name = Column('user_name',String(20)) 

    addresses = relationship("Address",backref="user") 

class Address(Base): 
    __tablename__ = 'addresses' 

    id = Column('user_id',ForeignKey('users.user_id')) 
    address = Column('address',String(30)) 
    pk = Column('address_id',Integer,primary_key=1) 

if __name__ == "__main__": 
    engine = create_engine("sqlite://", echo = True) 
    Base.metadata.create_all(engine) 
    session = sessionmaker(bind=engine)() 

    u1 = User(name='japan') 
    session.add(u1) 
    session.commit() 
    u1.addresses.append(Address(address='a1')) 
    u1.addresses.append(Address(address='a2')) 
    session.flush() 
    q = session.query(User).join(User.addresses).all() 
    print "="*23,q 
+1

Esta solución evita el problema central. Todavía me pregunto cómo hacer esto con modelos dinámicamente mapeados usando SqlSoup. – Devin

1

con sopa sql

joined = server.session.query(table1).join((table2,table1.id == table2.id)) 
where = table1.createDate > start 
results = joined.filter(where).all() 
1

que tenía este mismo problema, así que pensé que agregaría la solución que se me ocurrió (basado en http://www.mail-archive.com/[email protected]/msg23735.html). Desde luego no es lo más limpio que he codificado nunca, pero utilizando el ejemplo anterior, sería aproximadamente:

from sqlalchemy import select 
aliased_table1 = select([ 
    table1.c.Id.label("renamed_id_col"), 
    table1.c.any_other_columns_you_want_returned_but_not_renamed, 
    ... 
]).correlate(None).alias() 
joined = server.join(aliased_table1, table2, aliased_table1.c.renamed_id_col == table2.Id) 
where = aliased_table1.c.createDate > start 
results = joined.filter(where).all() 
0

Una forma de esto es para etiquetar todas las columnas de una de las mesas, de modo que usted no tienen ninguna colisión de los nombres de columna:

table1 = server.tab1 
table2 = server.with_labels(server.tab2) 
joined = server.join(table1,table2, table1.Id == table2.tab2_Id) 
where = table1.createDate > start 
results = joined.filter(where).all() 

tabla2 termina siendo una tabla etiquetada, donde todos los nombres de las columnas están precedidos por el nombre de la tabla, a fin de no interferir con los nombres de columna en la tabla 1.

Cuestiones relacionadas