Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Разработка баз данных _ Снова о QSqlRelationalTableModel

Автор: mva 26.6.2009, 15:46

Все примеры использования QSqlRelationalTableModel сделаны для демонстрации работы с одним столбцом из другой таблицы. Как быть, если мне нужно взять несколько столбцов из другой таблицы?

Автор: SABROG 26.6.2009, 15:57

Я активно не работал с этим классом и отказался от него из-за того, что он не отображает строки, где не находится "отношение" - ключ ссылается на данные, которых нет. Мне для задачи надо было перевязывать ключи динамически, отвязывать когда не нужны. А если не показывается строка, которую можно "перевязать", то и работать с этим классом нельзя.

Автор: Litkevich Yuriy 26.6.2009, 16:51

mva, а что именно тебе не понятно?
У меня в одной из таблиц несколько столбцов, и вопросов даже не возникло.

Автор: mva 26.6.2009, 17:19

http://www.doc.crossplatform.ru/qt/4.3.2/qsqlrelationaltablemodel.html

В нем таблица city имеет 2 поля: id и name.
А если, предположим, эта таблица имеет еще поля? Ну, например, почтовый индекс и междугородный телефонный код (поля таблицы city: id, name, post_index, phone_code) и мне их нужно отобразить?

Как строить реляции? Как в таком случае писать?

model->setTable("employee");
model->setRelation(2, QSqlRelation("city", "id", "name"));
model->setRelation(2, QSqlRelation("city", "id", "post_index"));
model->setRelation(2, QSqlRelation("city", "id", "phone_code"));

Так что ли?

Это что, все эти значения (name, post_index, phone_code) запишутся во второй столбец? Или я чего-то не понимаю?

Автор: SABROG 26.6.2009, 17:36

Я чего-то не понимаю. В отношении всегда 2 объекта:
- объект, который ссылается
- объект на который ссылаются

Если есть Петя, в поле "адрес" у которого ключ 1. В другой таблице по ключу 1 стоит "Мухосранск, 10, кв.20".
Ключ "1" не может ссылаться сразу на 2 и более объекта. Например "номер пасспорта", "телефонный номер" и "приводы в милицию".

Вернее, теоретически может. Но обычно все PRIMARY ключи - автоинкрементируемые. Если только в одну из перечисленных полей добавится запись, то ключи перестанут совпадать. Это должна быть какая-то синхронность редактирования БД чтоль.

Автор: mva 26.6.2009, 17:48

Есть конечно вариант использовать не таблицу employee, а ее просмотр, в котором для каждого поля внешней таблицы city сделать свой ключ - копию ключа city. Например так:

CREATE VIEW vw_employee AS
SELECT ID, Name, City AS city_name, City AS city_post_index, City AS city_phone_code , Country
FROM employee


А потом в приложении написать:

model->setTable("vw_employee");
model->setRelation(2, QSqlRelation("city", "id", "name"));
model->setRelation(3, QSqlRelation("city", "id", "post_index"));
model->setRelation(4, QSqlRelation("city", "id", "phone_code"));

Этот вариант прокатит, но не хотелось бы использовать такие "костыли" - некрасиво. И возможность редактирования таблицы employee здесь теряется...



Цитата(SABROG @ 26.6.2009, 18:36) *
Я чего-то не понимаю. В отношении всегда 2 объекта:
- объект, который ссылается
- объект на который ссылаются

Если есть Петя, в поле "адрес" у которого ключ 1. В другой таблице по ключу 1 стоит "Мухосранск, 10, кв.20".
Ключ "1" не может ссылаться сразу на 2 и более объекта. Например "номер пасспорта", "телефонный номер" и "приводы в милицию".

Вернее, теоретически может. Но обычно все PRIMARY ключи - автоинкрементируемые. Если только в одну из перечисленных полей добавится запись, то ключи перестанут совпадать. Это должна быть какая-то синхронность редактирования БД чтоль.


Все правильно, в отношении "один-к-одному" всегда 2 объекта. Но, у каждого из этих объектов может быть несколько атрибутов. Например, у Пети может быть задан день рождения и место рождения, а может еще что-то. Так вот, у проживающего по адресу "Мухосранск, 10, кв.20" я хочу знать ФИО, дату рождения и где он родился. Или мне для каждого атрибута отдельную таблицу заводить? Отдельно таблицу для дат рождения с двумя полями, отдельно таблицу мест рождений тоже с двумя полями. Так что ли?

Автор: Litkevich Yuriy 26.6.2009, 17:55

Цитата(mva @ 26.6.2009, 21:19) *
Это что, все эти значения (name, post_index, phone_code) запишутся во второй столбец? Или я чего-то не понимаю?
не угадал, в третий, т.к. используется не номер, а индекс столбца.

Цитата(mva @ 26.6.2009, 21:19) *
у, например, почтовый индекс и междугородный телефонный код (поля таблицы city: id, name, post_index, phone_code) и мне их нужно отобразить?

Вот и запиши на бумажке:
create table city{
id,                  /* idx=0 */
name,            /* idx=1 */
post_index,    /*  idx=2 */
phone_code   /*  idx=3 */
}


И код:
model->setTable("employee");
model->setRelation(2, QSqlRelation("city", "id", "name"));

А теперь расшифруй запись во втрой строке и связь с таблицей employee

Автор: mva 26.6.2009, 17:55

Цитата(Litkevich Yuriy @ 26.6.2009, 18:51) *
Цитата(mva @ 26.6.2009, 21:19) *
Это что, все эти значения (name, post_index, phone_code) запишутся во второй столбец? Или я чего-то не понимаю?
не угадал, в третий, т.к. используется не номер, а индекс столбца.


Я имею ввиду конечно индекс и нумерацию с 0. В примере написано "2", значит "второй", стоял бы "0" - тогда был бы "нулевой".

Но это не суть...

Автор: Litkevich Yuriy 26.6.2009, 18:04

mva, по сути ты не понял, что есть реляционная (относительная) связь в БД. Это место для себя прояснишь, отпадёт вопрос с Qt.

Цитата(mva @ 26.6.2009, 21:19) *
Возьмем этот пример
этот пример акуратно имеет два столбца с реляционными связями
City и Country

Автор: SABROG 26.6.2009, 18:06

Кажется я понял о чем ты. Если есть таблицы:

User:
id, name, country_key, city_key, address_key

country:

id, name, GPS

city:

id, name, population, GMT

address:

id, street, room, phone


То вместо:

Вася, Россия, Мухосранск, ул. Ленина, 25

ты хочешь получать:

Вася, Россия,[GPS], Мухосранск, [pupulation], [GTM], ул. Ленина, 25, [room], [phone]

Так?

Автор: mva 26.6.2009, 18:11

Цитата(Litkevich Yuriy @ 26.6.2009, 18:58) *
mva, по сути ты не понял, что есть реляционная (относительная) связь в БД. Это место для себя прояснишь, отпадёт вопрос с Qt.


С реляционными БД я работаю очень давно (на Visual FoxPro, до этого на FoxPro 2.6. Примерно с 92-го года), хорошо представляю себе что такое...

А вот Qt хотя мне в целом нравится, но в плане работы с базами данных представляется мне несколько корявой.

Но вернемся к вопросу...

model->setTable("employee");
model->setRelation(2, QSqlRelation("city", "id", "name"));


Что означает здесь циферка 2? Она означает, что во втором (т.е. третьем) столбце находится внешний ключ, по которому мы найдем соответствующую запись в таблице city, и подставим вместо него (ключа) значение поля Name из нее. Правильно? Как мне сказать Qt, что я хочу из найденной записи взять еще поле phone_code?

model->setRelation([b]3[/b], QSqlRelation("city", "id", "phone_code"));


Так?




Цитата(SABROG @ 26.6.2009, 19:06) *
Кажется я понял о чем ты. Если есть таблицы:

User:
id, name, country_key, city_key, address_key

country:

id, name, GPS

city:

id, name, population, GMT

address:

id, street, room, phone


То вместо:

Вася, Россия, Мухосранск, ул. Ленина, 25

ты хочешь получать:

Вася, Россия,[GPS], Мухосранск, [pupulation], [GTM], ул. Ленина, 25, [room], [phone]

Так?


Примерно так. Я хочу получить НЕСКОЛЬКО полей из таблицы, на которую ссылается ключ таблицы.

Автор: Litkevich Yuriy 26.6.2009, 18:32

Цитата(mva @ 26.6.2009, 22:11) *
Что означает здесь циферка 2? Она означает, что во втором (т.е. третьем) столбце таблицы employee находится внешний ключ, по которому мы найдем соответствующую запись в таблице который ссылается на поле id таблицы city, и подставим вместо него (ключа) значение поля Name из нее. Правильно?
здесь всё верно. Разме что я бы сказал более точно (выделил)

Цитата(mva @ 26.6.2009, 22:11) *
Как мне сказать Qt, что я хочу из найденной записи взять еще поле phone_code?
с помощью только QSqlRelationalTableModel ни как, одно поле заменяется на другое и всё! (одно на одно)

Можно поступить так, наиболее простое решение, создать вычисляемый столбец в связанной таблице, и подставлять его.

Вот пример:

Здесь столбец "Т.У." Это вычисляемое поле в БД (Имя подстанции и номер ячейки, плюс текст "яч.")

Автор: mva 26.6.2009, 18:36

Цитата(Litkevich Yuriy @ 26.6.2009, 19:26) *
с помощью только QSqlRelationalTableModel ни как, одно поле заменяется на другое и всё! (одно на одно)

Можно поступить так, наиболее простое решение, создать вычисляемый столбец в связанной таблице, и подставлять его.


В-о-о-т.... Уже кое-что проясняется... Т.е. вы предлагаете сделать конкатенацию нужных мне полей из связанной таблицы и подставлять ее? Но там же записаны выражения различной длины и если их "слепить вместе", то в этом столбце получится каша...

Автор: Litkevich Yuriy 26.6.2009, 19:55

Цитата(mva @ 26.6.2009, 22:36) *
Но там же записаны выражения различной длины и если их "слепить вместе", то в этом столбце получится каша...
почему каша?

Автор: mva 27.6.2009, 4:22

Цитата(Litkevich Yuriy @ 26.6.2009, 20:55) *
Цитата(mva @ 26.6.2009, 22:36) *
Но там же записаны выражения различной длины и если их "слепить вместе", то в этом столбце получится каша...
почему каша?


Н-е-е-е... Мне в отдельные столбцы надо... Еще есть какие-нибудь варианты?

Автор: Litkevich Yuriy 27.6.2009, 5:36

mva, про отдельные столбцы желания не понимаю.
Т.к. если они будут редактируемые то несколько столбцов должны будут одновременно свои значения менять, чтобы сохранить реляционную связь.

Автор: mva 27.6.2009, 19:10

Цитата(Litkevich Yuriy @ 27.6.2009, 6:36) *
mva, про отдельные столбцы желания не понимаю.
Т.к. если они будут редактируемые то несколько столбцов должны будут одновременно свои значения менять, чтобы сохранить реляционную связь.


Такое ощущение, что вы совсем не работали с реляционными базами данных. Если я изменяю атрибуты (поля) связанной таблицы, то это не значит, что реляционная связь теряется, т.к. я не трогаю значения ключей.

Ладно, я уже понял, что в Qt нет полноценной работы с реляционными отношениями таблиц. На таком уровне, как например в Visual FoxPro. Оно и не удивительно, т.к. все это хозяйство передано на уровень SQL серверов.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)