Исследование показало, что 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.
Комментариев нет:
Отправить комментарий