How to relationship with mysql table in QT QSqlRelationalTableModel? - c++

I am trying to work with QSqlRelationalTableModel of QT. I am new to MySQL table relationship but still I tried and can't make it work properly in QT.
I can get the result from MySQL:
create table stu(idd int auto_increment primary key,stu_name varchar(60),stu_age int);
create table stuInfo(idd int auto_increment primary key,stu_city varchar(60),stu_sub varchar(100), foreign key(id) references stu(id));
select stu.stu_name,stuInfo.stu_city from stu inner join stuInfo on stu.id=stuInfo.id;
To retrieve data from MySQL :
select stu.stu_name,stuInfo.stu_city from stu inner join stuInfo on stu.id=stuInfo.id;
In QT I can't make it work. I am getting confused with setRelation() and QSqlRelation() . I am not exactly understanding that how I can execute the same query in QT, I tried it in various way but sometime I get blank data, ugly header, errors etc.
Here is my learning code:
model = new QSqlRelationalTableModel();
model->setTable("stu");
model->setRelation(0,QSqlRelation("stu","id","stu_name","stu_age"));
model->setRelation(0,QSqlRelation("stuInfo","id","stu_city","stu_sub"));
model->select();
ui->tableView->setModel(model);

A QSqlRelation replaces the value of a field by the value of the other field in the relation, the replaced field won't appear in the query anymore, so you can't have 2 relations assigned to the same column, and you can't assign a relation to the primary key (as stated in the documentation of setRelation).
Basically the structure for which QSqlRelationalTableModel should be used would be a main table which would have 1 or more foreign index fields, and each of these fields could be replaced by the value of a chosen field in the tables from which the foreign indexes comes from (e.g.: to replace a "city_id" numerical field in the main table by the name of the city coming from another table for which that "city_id" is the primary key).
For what you want to do, you should use QSqlQueryModel with a manually constructed query instead of QSqlRelationalTableModel.

The problem is that your code does not really express the model you described.
You have a primary table called stuInfo, which references another table called stu.
To do this in Qt, you should create a table based on "stuInfo" (and not "stu"!):
model=new QSqlRelationalTableModel();
model->setTable("stuInfo");
Then you can implement your foreign key, as a relation:
model->setRelation(3,QSqlRelation("stu","id","stu_name"));
You need to point to index "3", which is the position of the reference field "id", on stuInfo table (0 will point to the primary key, which is not what you want!). The parameters of the QsqlRelation are the reference table name ("stu") the primary field name ("id") and the reference table field to which you want to point: in this case I am pointing to "stu_name"; if I wanted to point to the age, I could do something like this instead:
model->setRelation(3,QSqlRelation("stu","id","stu_age"));
After this code:
model->select();
ui->tableView->setModel(model);
you should have a view that shows you all the fields on stuInfo, and whose last field ("id") is mapped to the name (or age) on the "stu" table;

Related

Define unique columns on ManyToMany in Doctrine

I'm trying to add unique columns on a pivot table created via a ManyToMany association.
I found this page of the documentation explaining how to generate a database unique constraint on some columns with this example:
/**
* #Entity
* #Table(name="ecommerce_products",uniqueConstraints={#UniqueConstraint(name="search_idx", columns={"name", "email"})})
*/
class ECommerceProduct
{
}
But this only works if I create the pivot table via a third entity and, in my case, I created the pivot table using a ManyToMany relation (in the same fashion as this code).
Is there a way to add unique columns on pivot table while still using ManyToMany or do I need to rely on a third entity?
While #Table annotation proposes a uniqueConstraints option, #JoinTable does not. Thus, if you want to add a unique constraint on your association table, you will have to actually create another entity explicitly.
That being said, the default join table should not need anything more than the default configuration set up by Doctrine. Currently, when adding a ManyToMany association, the join table is composed of two fields and a composite primary key relying on both fields is created.
If your association table only contains the two basic fields referring to both sides of your association (which is necessarily the case if you use #ManyToMany), the composite primary key should be all you need.
Here is the generated SQL for the basic example where a User has a ManyToMany association with Group (from this section of the documentation):
CREATE TABLE users_groups (
user_id INT NOT NULL,
group_id INT NOT NULL,
PRIMARY KEY(user_id, group_id)
) ENGINE = InnoDB;
ALTER TABLE users_groups ADD FOREIGN KEY (user_id) REFERENCES User(id);
ALTER TABLE users_groups ADD FOREIGN KEY (group_id) REFERENCES Group(id);
As you can see, everything is properly set up with a composite primary key which will ensure that there can't be duplicate entries for the couple (user_id, group_id).
Of course there is another alternative, Alan!
If you need a Zero to Zero relationship, the only alternative is defining the unique constraint per each pk in the agregated table, to make doctrine figuring out about zero to zero relationship.
The problem is that Doctrine's people hadn't considered zero to zero relationships, so the only alternative for this is manytomany relationship with one unique constraint per pk.
If you have doubts about final-state of your doctrine implementation of your E-R model, I strongly recommend mysql-workbench-schema-exporter. With this php tool, you can easily export your mysql workbench E-R schema to a Doctrine's working classes schema, so you would be able to easily explore all your alternatives ;-)
Hope this helps

how to use foreign-keys with hsql create table?

could someone explain me how to use foreign keys in hsql?
I would like it in an create table, but working alter table is also ok.
I am working without tools, just in eclipse
whats wrong with the hsql code?
CREATE TABLE user(
t_id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY,
name VARCHAR(30),
lastname VARCHAR(30),
email VARCHAR(30),
--FOREIGN KEY (b_id) REFERENCES bookingnumber(b_id)
);
CREATE TABLE bookingnumber (
b_id INTEGER PRIMARY KEY
);
ALTER TABLE user
ADD FOREIGN KEY (fk_b_id) REFERENCES bookingnumber(b_id);
Perhaps you are trying to link each booking number to a user. In this case, multiple booking numbers may exist for each user. If you want to do this, add a column T_ID to the BOOKINGNUMBER table and created the foreign key on this table.
But your statement is linking each user to a booking number and doesn't have the correct syntax. It needs a column named B_ID in the USER table to work. And the syntax would be like this:
ALTER TABLE user ADD FOREIGN KEY (b_id) REFERENCES bookingnumber(b_id);
I was facing a similar situation and this helped me
CREATE TABLE child(c1 INTEGER, c2 VARCHAR, FOREIGN KEY (c1, c2) REFERENCES parent(p1, p2));
A more detailed explanation can be found at http://www.d.umn.edu/~tcolburn/cs4531/hsqldb_docs/guide/guide.html#N102F8

Which is better? city.state.id or city.state_id

I have to table with relation.
State
id
name
City
id
name
state
Which is better in performance?
city.state.id or city.state_id
city.state_id is better anyway. city.state will do another fetch from database.You can avoid this using select_related.If you need only id of foriegn key, no need of select_related here.Just do city.state_id(since foriegn key id will fetch in the query which gives city object).
city.state_id is better than city.state.id. Because It makes only a query instead of two.
BTW, You can use Django Debug Toolbar for debugging queries.
the <field>_id field you see is the database column name
docs
Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column
So this means it doesn't need to make a separate query to retrieve the foreign key instance (See Select a single field from a foreign key for more details).
But this assumes you haven't used select_related or prefetch_related

Open JPA how do I get back results from foreign key relations

Good morning. I have been looking all over trying to answer this question.
If you have a table that has foreign keys to another table, and you want results from both tables, using basic sql you would do an inner join on the foreign key and you would get all the resulting information that you requested. When you generate your JPA entities on your foreign keys you get a #oneToone annotation, #oneToMany, #ManyToMany, #ManyToOne, etc over your foreign key columns. I have #oneToMany over the foreign keys and a corresponding #ManyToOne over the primary key in the related table column I also have a #joinedON annotation over the correct column... I also have a basic named query that will select everything from the first table. Will I need to do a join to get the information from both tables like I would need to do in basic sql? Or will the fact that I have those annotations pull those records back for me? To be clear if I have table A which is related to Table B based on a foreign key relationship and I want the records from both tables I would join table A to B based on the foreign key or
Select * From A inner Join B on A.column2 = B.column1
Or other some-such non-sense (Pardon my sql if it is not exactly correct, but you get the idea)...
That query would have selected all column froms A and B where those two selected column...
Here is my named query that I am using....
#NamedQuery(name="getQuickLaunch", query = "SELECT q FROM QuickLaunch q")
This is how I am calling that in my stateless session bean...
try
{
System.out.println("testing 1..2..3");
listQL = emf.createNamedQuery("getQuickLaunch").getResultList();
System.out.println("What is the size of this list: number "+listQL.size());
qLaunchArr = listQL.toArray(new QuickLaunch[listQL.size()]);
}
Now that call returns all the columns of table A, but it lack's the column's of table B. My first instinct would be to change the query to join the two tables... But that kind of makes me think what is the point of using JPA then if I am just writing the same queries that I would be writing anyway, just in a different place. Plus, I don't want to overlook something simple. So what say you stack overflow enthusiasts? How does one get back all the data of joined query using JPA?
Suppose you have a Person entity with a OneToMany association to the Contact entity.
When you get a Person from the entityManager, calling any method on its collection of contacts will lazily load the list of contacts of that person:
person.getContacts().size();
// triggers a query select * from contact c where c.personId = ?
If you want to use a single query to load a person and all its contacts, you need a fetch in the SQL query:
select p from Person p
left join fetch p.contacts
where ...
You can also mark the association itself as eager-loaded, using #OneToMany(lazy = false), but then every time a person is loaded (vie em.find() or any query), its contacts will also be loaded.

Django AutoField not returning new primary_key

We've got a small problem with a Django project we're working on and our postgresql database.
The project we're working on is a site/db conversion from a PHP site to a django site. So we used inspect db to generate the models from the current PHP backend.
It gave us this and we added the primary_key and unique equals True:
class Company(models.Model):
companyid = models.IntegerField(primary_key=True,unique=True)
...
...
That didn't seem to be working when we finally got to saving a new Company entry. It would return a not-null constraint error, so we migrated to an AutoField like below:
class Company(models.Model):
companyid = models.AutoField(primary_key=True)
...
...
This saves the Company entry fine but the problem is when we do
result = form.save()
We can't do
result.pk or result.companyid
to get the newly given Primary Key in the database (yet we can see that it has been given a proper companyid in the database.
We are at a loss for what is happening. Any ideas or answers would be greatly appreciated, thanks!
I just ran into the same thing, but during a django upgrade of a project with a lot of history. What a pain...
Anyway, the problem seems to result from the way django's postgresql backend gets the primary key for a newly created object: it uses pg_get_serial_sequence to resolve the sequence for a table's primary key. In my case, the id column wasn't created with a serial type, but rather with an integer, which means that my sequence isn't properly connected to the table.column.
The following is based on a table with the create statement, you'll have to adjust your table names, columns and sequence names according to your situation:
CREATE TABLE "mike_test" (
"id" integer NOT NULL PRIMARY KEY,
"somefield" varchar(30) NOT NULL UNIQUE
);
The solution if you're using postgresql 8.3 or later is pretty easy:
ALTER SEQUENCE mike_test_id_seq OWNED BY mike_test.id;
If you're using 8.1 though, things are a little muckier. I recreated my column with the following (simplest) case:
ALTER TABLE mike_test ADD COLUMN temp_id serial NOT NULL;
UPDATE mike_test SET temp_id = id;
ALTER TABLE mike_test DROP COLUMN id;
ALTER TABLE mike_test ADD COLUMN id serial NOT NULL PRIMARY KEY;
UPDATE mike_test SET id = temp_id;
ALTER TABLE mike_test DROP COLUMN temp_id;
SELECT setval('mike_test_id_seq', (SELECT MAX(id) FROM mike_test));
If your column is involved in any other constraints, you'll have even more fun with it.