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