У меня проблемы с выполнением запроса SQLAlchemy между двумя таблицами:
ProcessedDataset
- ID
ProcDSParent
- ThisDataset (foreign key to ProcessedDataset.ID)
- ItsParent (foreign key to ProcessedDataset.ID)
Чтобы найти Parent
и Child
для Dataset
, мне нужно явно указать последовательность соединения между: ProcessedDataset
<- <code>ProcDSParent -> ProcessedDataset
После создания для них другого псевдонима, я пробую другой подход к объединению, но все равно не могу его получить.
Демонстрация с помощью findParent
из Dataset
:
dataset = DB.db_tables[db_alias]['ProcessedDataset']
dsparent = DB.db_tables[db_alias]['ProcDSParent']
parent = dataset.alias('ProcessedDataset_ItsParent')
child_parent = dsparent.alias('ThisDataset_ItsParent')
keylist = [parent.c.Name]
whereclause = dataset.c.Name.op('=')('Test')
FromClause.join + expression.select
r_join = dataset
r_join.join(child_parent, dataset.c.ID == child_parent.c.ThisDataset)
r_join.join(parent, child_parent.c.ItsParent == parent.c.ID)
query = select(keylist, from_obj=r_join, whereclause=whereclause)
print query
SELECT `ProcessedDataset_ItsParent`.`Name`
FROM `ProcessedDataset` AS `ProcessedDataset_ItsParent`, `ProcessedDataset`
WHERE `ProcessedDataset`.`Name` = %s
orm.join + expression.select
join2 = join(dataset, child_parent, dataset.c.ID == child_parent.c.ThisDataset)
join2.join(dsparent, child_parent.c.ItsParent == parent.c.ID)
print query
SELECT `ProcessedDataset_ItsParent`.`Name`
FROM `ProcessedDataset` AS `ProcessedDataset_ItsParent`,
`ProcessedDataset` INNER JOIN `ProcDSParent` AS `ThisDataset_ItsParent` ON
`ProcessedDataset`.`ID` = `ThisDataset_ItsParent`.`ThisDataset`
WHERE `ProcessedDataset`.`Name` = %s
Как видите, ни один изэто Parent
из Dataset
, что должно быть:
SELECT `ProcessedDataset_ItsParent`.`Name`
FROM `ProcessedDataset`
INNER JOIN `ProcDSParent` AS `ThisDataset_ItsParent` ON
`ProcessedDataset`.`ID` = `ThisDataset_ItsParent`.`ThisDataset`
INNER JOIN `ProcessedDataset` AS `ProcessedDataset_ItsParent` ON
`ThisDataset_ItsParent`.'ItsParent` = `ProcessedDataset_ItsParent`.`ID`
WHERE `ProcessedDataset`.`Name` = %s
Цените любую помощь, застрявшую здесь уже пару дней!
Донг
Прикрепление минимального кода DDL и кода Python
CREATE TABLE ProcessedDataset
(
ID BIGINT UNSIGNED not null auto_increment,
Name varchar(500) not null,
primary key(ID)
) ;
CREATE TABLE ProcDSParent
(
ID BIGINT UNSIGNED not null auto_increment,
ThisDataset BIGINT UNSIGNED not null,
ItsParent BIGINT UNSIGNED not null,
primary key(ID),
unique(ThisDataset,ItsParent)
) ;
ALTER TABLE ProcDSParent ADD CONSTRAINT
ProcDSParent_ThisDataset_FK foreign key(ThisDataset) references ProcessedDataset(ID) on delete CASCADE
;
ALTER TABLE ProcDSParent ADD CONSTRAINT
ProcDSParent_ItsParent_FK foreign key(ItsParent) references ProcessedDataset(ID) on delete CASCADE
;
INSERT INTO ProcessedDataset VALUES (0, "ds0");
INSERT INTO ProcessedDataset VALUES (1, "ds1");
INSERT INTO ProcessedDataset VALUES (2, "ds2");
INSERT INTO ProcessedDataset VALUES (3, "ds3");
INSERT INTO ProcessedDataset VALUES (4, "ds4");
INSERT INTO ProcessedDataset VALUES (5, "ds5");
INSERT INTO ProcessedDataset VALUES (6, "ds6");
INSERT INTO ProcessedDataset VALUES (7, "ds7");
INSERT INTO ProcDSParent VALUES (0, 0, 1);
INSERT INTO ProcDSParent VALUES (1, 2, 1);
INSERT INTO ProcDSParent VALUES (2, 1, 3);
INSERT INTO ProcDSParent VALUES (3, 3, 4);
INSERT INTO ProcDSParent VALUES (4, 5, 6);
INSERT INTO ProcDSParent VALUES (5, 7, 6);
(ds0, ds2) -> ds1 -> ds3 -> ds4
(ds5, ds7) -> ds6
from sqlalchemy import Table, create_engine, MetaData
from sqlalchemy import and_
from sqlalchemy.sql import select
from sqlalchemy.orm import join
url = 'mysql://cms:passcms@localhost:3306/testbed'
engine = create_engine(url, strategy = 'threadlocal')
kwargs = {'autoload':True}
db_meta = MetaData()
db_meta.bind = engine
dataset = Table('ProcessedDataset', db_meta, **kwargs)
dsparent = Table('ProcDSParent', db_meta, **kwargs)
parent = dataset.alias('ProcessedDataset_ItsParent')
child_parent = dsparent.alias('ThisDataset_ItsParent')
keylist = [parent.c.Name]
whereclause = dataset.c.Name.op('=')('ds0')
r_join = dataset
r_join.join(child_parent, dataset.c.ID == child_parent.c.ThisDataset)
r_join.join(parent, child_parent.c.ItsParent == parent.c.ID)
query = select(keylist, whereclause)
print query
print engine.execute(query).fetchall()
query.append_from(r_join)
print query
print engine.execute(query).fetchall()
query = select(keylist, from_obj=r_join, whereclause=whereclause)
print query
print engine.execute(query).fetchall()
join2 = join(dataset, child_parent, dataset.c.ID == child_parent.c.ThisDataset)
join2.join(dsparent, child_parent.c.ItsParent == parent.c.ID)
query.append_from(join2)
print query
print engine.execute(query).fetchall()
query = select(keylist, from_obj=join2, whereclause=whereclause)
print query
print engine.execute(query).fetchall()