I created this recursive query:
element0 = aliased(Territoire)
sub_territories = session.query(element0, element0.id). \
filter(element0.id == 1). \
filter(element0.scale != 'Region'). \
cte(name='sub_territories', recursive=True)
st_alias = aliased(sub_territories)
relation = aliased(parent_child)
porteur = aliased(Territoire)
corps = session.query(porteur, relation.c.child_id). \
join(porteur, porteur.id == relation.c.child_id). \
join(st_alias, relation.c.parent_id == st_alias.c.id). \
filter(st_alias.c.scale != 'Region')
sub_territories = sub_territories.union(corps)which should give all the children of element0 recursively, stopping at the 'Region' level(items are linked by a many-to-many relation), each item having a level which can be : world, country, region, city...
here is some code that could help you:
class Territoire(Base):
__tablename__ = 'territoire'
id = Column(Integer, primary_key=True)
name = Column(String)
scale = Column(String)
children = relationship(
'Territoire',
secondary=parent_child,
back_populates='parents',
primaryjoin=parent_child.c.parent_id == id,
secondaryjoin=parent_child.c.child_id == id,
)
parents = relationship(
'Territoire',
secondary=parent_child,
primaryjoin=parent_child.c.child_id==id,
secondaryjoin=parent_child.c.parent_id==id,
back_populates='children'
)and the table:
parent_child = Table('parent_child', Base.metadata,
Column('parent_id', ForeignKey('territoire.id'), primary_key=True),
Column('child_id', ForeignKey('territoire.id'), primary_key=True))the error message is :
sqlalchemy.exc.ArgumentError: All selectables passed to CompoundSelect must have identical numbers of columns; select #1 has 3 columns, select #2 has 4
I don't understand this error, since the 2 CTE requests have for 1st element a Territoire object and for 2nd element an int (id).
thank you
thank you
--SQLAlchemy -The Python SQL Toolkit and Object Relational MapperTo post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.---You received this message because you are subscribed to the Google Groups "sqlalchemy" group.To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.To post to this group, send email to sqlal...@googlegroups.com.Visit this group at https://groups.google.com/group/sqlalchemy.To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/04358259-dd87-4dcb-b24a-8c81f82109f0%40googlegroups.com.For more options, visit https://groups.google.com/d/optout.
from sqlalchemy import Column, Integer, String, ForeignKey, create_engine
from sqlalchemy import Column, Integer, String, ForeignKey, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker, aliased
from sqlalchemy.schema import Table
Base = declarative_base()
parent_child = Table('parent_child', Base.metadata,
Column('parent_id', ForeignKey('territoire.id'), primary_key=True),
Column('child_id', ForeignKey('territoire.id'), primary_key=True))
class Territoire(Base):
__tablename__ = 'territoire'
id = Column(Integer, primary_key=True)
name = Column(String)
scale = Column(String)
children = relationship(
'Territoire',
secondary=parent_child,
back_populates='parents',
primaryjoin=parent_child.c.parent_id == id,
secondaryjoin=parent_child.c.child_id == id,
)
parents = relationship(
'Territoire',
secondary=parent_child,
primaryjoin=parent_child.c.child_id==id,
secondaryjoin=parent_child.c.parent_id==id,
back_populates='children'
)
def __repr__(self):
chaine1= "<Territoire(%s // %s // %s)>" % (self.id, self.name, self.scale)
return chaine1
def __init__(self, name, scale):
self.name = name
self.scale = scale
self.parents=[]
self.children=[]
if __name__ == "__main__":
engine = create_engine('postgresql://postgres:admin@localhost/territoires2', echo=True)
# Base = declarative_base()
Session = sessionmaker(bind=engine)
Session.configure(bind=engine)
Base.metadata.create_all(engine)
session = Session()
# print("territoire table="+Territoire.__table__)
france = Territoire(name="france", scale="pays")
metz = Territoire(name='metz', scale='ville')
grand_est = Territoire(name='Grand Est', scale='region')
metz.parents.append(grand_est)
grand_est.parents.append(france)
var = Territoire('Var', 'region')
france.children.append(var)
sete = Territoire('sete', 'ville')
var.children.append(sete)
session.add_all([france, metz, grand_est])
session.add_all([var,sete])
# +++++++++++++++++++++++
# **********************************************
session.commit()
# **********************************************
# for t in session.query(Territoire):
# print(t)
element0 = aliased(Territoire)
sub_territories = session.query(element0.id,element0.name,element0.scale). \
filter(element0.id == 1). \
filter(element0.scale != 'region'). \
cte(name='sub_territories', recursive=True)
# st_alias = aliased(sub_territories,name="sa")
relation = aliased(parent_child, name="rel")
porteur = aliased(Territoire, name="p")
rec=aliased(sub_territories,name="rec")
sub_territories = sub_territories.union(
session.query(porteur.id,porteur.name,porteur.scale). \
# filter(porteur.id == relation.c.child_id). \
filter(porteur.id == relation.c.child_id). \
filter(relation.c.parent_id == sub_territories.c.id). \
filter(sub_territories.c.scale != 'region'))
# sub_territories = sub_territories.union(corps)
print(sub_territories)
q = session.query(Territoire).select_from(sub_territories)
print('solution =' + str(q.all()))my problem seems to be logical, I will try to solve it, but maybe someone could help me to go faster!thank you
--SQLAlchemy -The Python SQL Toolkit and Object Relational MapperTo post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.---You received this message because you are subscribed to the Google Groups "sqlalchemy" group.To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.To post to this group, send email to sqlal...@googlegroups.com.Visit this group at https://groups.google.com/group/sqlalchemy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/abac3ac5-fac3-42f9-aa4f-1f4268b202c2%40googlegroups.com.