Slick 3 unique constraint between two keys - slick-3.0

I have a SQL model
create table "model" (
"id" BIGINT PRIMARY KEY NOT NULL DEFAULT nextval('venue_id_seq'),
"description" VARCHAR NOT NULL,
"prop_a" BIGINT,
"prop_b" BIGINT,
unique(prop_a, prop_b)
);
Is it possible in the slick schema definition to define this constraint or do we need to handle the exception?

I suppose you mean unique index on db level. You can define it like here:
def idx = index("model_unique", (prop_a, prop_b), unique = true)
Obviously you put it into your Slick table definition (aka Mixed Type)

Related

Django isn't creating db constraints for foreign keys with SQLite

I'm using Django 3.0.6
I'm adding ForeignKey and ManyToManyField to my models, but I've noticed that django creates the INDEX, but not the actual FOREIGN KEY constraints in the db.
I've tried to explicitly set db_constraint=True but as expected is useless, since it's True by default.
I've found so many answers explaining this, but only for very old Django versions, doing tricks for enabling it when it was otherwise disabled. Now instead it should just work out of the box. Couldn't find anything AT ALL regarding Django 3.
Code
class Token (models.Model):
owner = models.ForeignKey(Chiefdom, on_delete=models.CASCADE, db_constraint=True)
county = models.ManyToManyField(County, db_constraint=True)
amount = models.PositiveSmallIntegerField()
SQLite
CREATE TABLE IF NOT EXISTS Piece_token (
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
amount smallint unsigned NOT NULL,
owner_id integer NOT NULL
);
CREATE INDEX IF NOT EXISTS Piece_token_owner_id_d27c77f0 ON Piece_token (owner_id);
CREATE TABLE IF NOT EXISTS Piece_token_county (
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
token_id integer NOT NULL,
county_id integer NOT NULL
);
CREATE INDEX IF NOT EXISTS Piece_token_county_county_id_57802417 ON Piece_token_county (county_id);
CREATE INDEX IF NOT EXISTS Piece_token_county_token_id_e7798ae9 ON Piece_token_county (token_id);
CREATE UNIQUE INDEX IF NOT EXISTS Piece_token_county_token_id_county_id_b06b16cc_uniq ON Piece_token_county (token_id, county_id);
I have checked now with same version of Django and SQLite there are all foreign keys present
For example
SELECT * FROM pragma_foreign_key_list('auth_user_groups');
Note all foreign keys are deferred and checked from Django -> source

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

django: how to create a column whose default value is now()?

I am using django model to create a table. And the table has a inserted_time column, and I am using plain sql to insert the data, so in the insert sql I don't want to care about this column since I expected database should auto fill now() to the column (using mysql). But how to create such column whose default value is now() in django model. I am using auto-now, but it doesn't work.
updated:
I created a model as:
class TestDaniel(models.Model):
inserted_time = models.DateTimeField(db_index = True,auto_now_add=True)
Then I checked the mysql database after migration, the definition of the table is:
CREATE TABLE `orajob_testdaniel` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`inserted_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `orajob_testdaniel_e69592ad` (`inserted_time`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
From the table definition, inserted_time doesn't have a default value, what I want is to have a default value of now() for column of inserted_time, So what I inserted data using SQL (not django model), it will auto populate that column as now()
Well, usage of default values for DateField is clearly declared in the Django documentation. Django DateField Documentation
According to the docs, you can do the following:
inserted_time = models.DateTimeField(auto_now_add=True)
This will set current datetime to this field. This value will be by default and will be set once you create an object. Warning: now, even if you set custom datetime to this field, it will be ignored!
It will not work if you create your object using plain SQL. Django should use its own ORM in order to set default values.

How to relationship with mysql table in QT QSqlRelationalTableModel?

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;

Entity-attribute-value mode or JSON in database?

I have a database schema where attribute are unlimited, I can have this structure using two ways.
Using Entity attribute-value model
table 1
id
entity
table 2
entityid
attribute-name
attribute-value
2 . Way is to use JSON.
like
table1
id
entity
json-attribute {"name":"value-pair"}
I have a question which way will be best and effective .
I am not familiar with a DBMS that would let you efficiently find all entities where someAttribute = x, if the entities were stored in a non-deconstructed canonical JSON representation. (But I would be eager to know about any.)
The first approach using two tables (at least) can accomplish this task, and it is therefore the more capable and the more flexible approach; a JSON representation of the entity always be constructed from the database recordset:
// all entities having a particular attribute
select entityid, attributeName, attributeValue
from ENTITIES INNER JOIN ENTITYATTRIBUTES
on ENTITY.ID = ENTITYATTRIBUTES.entityid
where ENTITIES.id IN
(
select distinct entityid from ENTITYATTRIBUTES
where attributename = ? and attributeValue = ?
)
OR
// the attributes for a specified entity
select attributeName, attributeValue
from ENTITIES INNER JOIN ENTITYATTRIBUTES
on ENTITY.ID = ENTITYATTRIBUTES.entityid
where ENTITIES.id = ?
Complexity could enter, of course, if attributes could themselves contain entities. Nesting of objects is possible in the JSON representation but in the database it requires either a multi-table relational mapping or an OODBMS that supports nested tables.
I had chosen json solution.
why ?
It will avoid writing complex query to fetch data.
What about if I need to load any particular attribute ?
yes. In JSON solution I have to load all attribute from the database. and then filter for that particular attribute.
But in my case I will be loading all attribute every time.
If I have a condition of loading particular attribute I might have chosen attribute value schema.