Исследование показало, что QRelationalTableMode.selectStatement возвращает запрос следующего вида:
SELECT tbl.fld1,
relTblAl_1.fld1 AS reftbl1_fld1_2,
relTblAl_2.fld1,
relTblAl_3.fld1,
tbl.fld2,
tbl.fld3,
FROM tbl,
reftbl1 relTblAl_1,
reftbl1 relTblAl_2,
reftbl2 relTblAl_3
WHERE ( tbl.fkfld1 = relTblAl_1.pkfld
AND tbl.fkfld2 = relTblAl_2.pkfld
AND tbl.fkfld3 = relTblAl_3.pkfld )
ORDER BY tbl.sortfld ASC
Это INNER JOIN, который действительно не выбирает строки с пустыми ссылками. Выход напрашивается - переписать selectStatement, что бы он возвращал правильный запрос, использующий LEFT JOIN. Тогда выберутся все строки таблицы
Запрос должен быть примерно таким:
SELECT tbl.fld1,
relTblAl_1.fld1 AS reftbl1_fld1_2,
relTblAl_2.fld1,
relTblAl_3.fld1,
tbl.fld2,
tbl.fld3,
FROM tbl
LEFT JOIN reftbl1 relTblAl_1
ON tbl.fkfld1 = relTblAl_1.pkfld
LEFT JOIN reftbl1 relTblAl_2
ON tbl.fkfld2 = relTblAl_2.pkfld
LEFT JOIN reftbl2 relTblAl_3
ON tbl.fkfld3 = relTblAl_3.pkfld
ORDER BY tbl.sortfld ASC
Унаследуем класс от QRelationalTableMode и перепишем метод:
class MDRelationalTableModel (QSqlRelationalTableModel): def selectStatement(self): u"""Вариант без использования метаданных, не чистите, может пригодиться""" tname = self.tableName() fields = [] joins = [] rec = self.record() for cid in xrange(rec.count()): fname = unicode(rec.fieldName(cid)) relation = self.relation(cid) if relation.isValid(): reftable = unicode(relation.tableName()) alias = u'relTblAl_{0}'.format(cid) reffld = unicode(relation.indexColumn()) fields.append(u'{0}.{1}'.format(alias, relation.displayColumn())) joins.append(u'left join {reftable} {alias} on {tname}.{fname} = {alias}.{reffld}'.format(**locals())) else: fields.append(u'{0}.{1}'.format(tname, fname)) filter = unicode(self.filter()) filter = u'1=1' if not filter else filter return QString(u'select {0} from {1} {2} where({3}) {4}'.format(u', '.join(fields), tname, u' '.join(joins), filter, unicode(self.orderByClause())))
Теперь модель содержит все необходимые строк. Думаю, написать тоже самое на C++ для чистого Qt тоже не составит никакого труда, благо модель хранит все необходимые для этого данные и всегда можно посмотреть код QRelationalTableMode.selectStatement.

0 коммент.:
Отправить комментарий