Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Снова о QSqlRelationalTableModel
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Разработка баз данных
mva
Все примеры использования QSqlRelationalTableModel сделаны для демонстрации работы с одним столбцом из другой таблицы. Как быть, если мне нужно взять несколько столбцов из другой таблицы?
SABROG
Я активно не работал с этим классом и отказался от него из-за того, что он не отображает строки, где не находится "отношение" - ключ ссылается на данные, которых нет. Мне для задачи надо было перевязывать ключи динамически, отвязывать когда не нужны. А если не показывается строка, которую можно "перевязать", то и работать с этим классом нельзя.
Litkevich Yuriy
mva, а что именно тебе не понятно?
У меня в одной из таблиц несколько столбцов, и вопросов даже не возникло.
mva
Возьмем этот пример

В нем таблица 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
Я чего-то не понимаю. В отношении всегда 2 объекта:
- объект, который ссылается
- объект на который ссылаются

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

Вернее, теоретически может. Но обычно все PRIMARY ключи - автоинкрементируемые. Если только в одну из перечисленных полей добавится запись, то ключи перестанут совпадать. Это должна быть какая-то синхронность редактирования БД чтоль.
mva
Есть конечно вариант использовать не таблицу 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
Цитата(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
Цитата(Litkevich Yuriy @ 26.6.2009, 18:51) *
Цитата(mva @ 26.6.2009, 21:19) *
Это что, все эти значения (name, post_index, phone_code) запишутся во второй столбец? Или я чего-то не понимаю?
не угадал, в третий, т.к. используется не номер, а индекс столбца.


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

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

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

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

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

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

Вот пример:
Нажмите для просмотра прикрепленного файла
Здесь столбец "Т.У." Это вычисляемое поле в БД (Имя подстанции и номер ячейки, плюс текст "яч.")
mva
Цитата(Litkevich Yuriy @ 26.6.2009, 19:26) *
с помощью только QSqlRelationalTableModel ни как, одно поле заменяется на другое и всё! (одно на одно)

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


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


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


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

Ладно, я уже понял, что в Qt нет полноценной работы с реляционными отношениями таблиц. На таком уровне, как например в Visual FoxPro. Оно и не удивительно, т.к. все это хозяйство передано на уровень SQL серверов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.