I don’t know how to resolve my situation:
create Table VIPUsers(
id int primary key,
parent int references Parent(id)
);
create Table Parent(
id int not null,
childType int not null,/*indicates ChildA or ChildB*/
unique (id,childType)
);
create index on Parent(id);
create Table ChildA(
parent int references Parent(id),
propertyA int
);
create Table ChildB(
parent int references Parent(id),
propertyB date
);
There is M to N relationship between tables VIPUsers
and ChildA
, ChildB
.
Table Parent
is a junction table containing information whether VIPUsers
uses instances of ChildA
and/or instances of ChildB
I need to add rows:
insert into Parent (id,subtype) values (1,1)
insert into Parent (id,subtype) values (1,2)
This gave me an error ‘duplicate primary key’ so I deleted the primary key and I’d use an index instead, just as it is shown above.
But now I can’t create tables VIPUsers
, ChildA
, ChildB
as I get the error
'there is no unique constraint matching given keys for referenced table ...'
I know it is because VIPUsers
would not reference a unique row. But that’s what I need. I need a join where for each parent I get one or more childTypes. For example:
VIPUsers ParentId childType
1 1 1
1 1 2
If I make Parent.id
a primary key, there will be only one childType
for each user. If I remove primary key, DBMS starts complaining about referencing a non unique column.
My goal is to then cross join the above example table with ChildA or ChildB on ParentId to get table like this:
VIPUsers ParentId childType ChildA.propertyA ChildB.propertyB
1 1 1 50 null
1 1 2 null 2/2/2017
And based on the childType
I’m able to tell what kind of information this row represents.
I don’t like putting childType
into each Child
table because it would allow for nonsense values like ChildA being of type ChildB and vice versa.
What are the usual ways of going about this?
I have my tenant model as this
class Company(TenantModel): tenant_id = "id" name = models.CharField(max_length=50) address = models.CharField(max_length=255) description = models.TextField(blank=True, null=True) email = models.CharField(max_length=255, blank=True, null=True) subdomain_prefix = models.CharField(max_length=255, blank=True, null=True) cell_phone = models.CharField(max_length=255, blank=True, null=True) active = models.BooleanField(default=True) land_phone = models.CharField(max_length=255, blank=True, null=True) country = models.CharField(max_length=32, choices=COUNTRY_CHOICES, blank=True) state = models.CharField(max_length=255, blank=True, null=True) city = models.CharField(max_length=255, blank=True, null=True) zip_code = models.CharField(max_length=255, blank=True, null=True) about = models.TextField(blank=True, null=True) contact_details = models.TextField(blank=True, null=True) latitude = models.CharField(max_length=512, blank=True, null=True) longitude = models.CharField(max_length=512, blank=True, null=True) year_established = models.DateField( blank=True, null=True) total_employees = models.CharField(max_length=255, blank=True, null=True) business_type = models.CharField(max_length=255, blank=True, null=True) main_products = models.CharField(max_length=255, blank=True, null=True) total_annual_revenue = models.CharField(max_length=255, blank=True, null=True) url = models.CharField(max_length=255, blank=True, null=True) social_link = models.CharField(max_length=255, blank=True, null=True) def __str__(self): return self.name class UserProfile(TenantModel): is_admin = models.BooleanField(default=False) title = models.CharField(max_length=255, blank=True, null=True) last_name = models.CharField(max_length=255, blank=True, null=True) first_name = models.CharField(max_length=255, blank=True, null=True) other_names = models.CharField(max_length=255, blank=True, null=True) address = models.CharField(max_length=255, blank=True, null=True) tenant_id = 'company_id' class Meta: abstract = True class SuperAdmin(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True) class Action(models.Model): action = models.TextField(null=True, blank=True) time = models.DateTimeField(auto_now=True) by = models.ForeignKey(SuperAdmin, on_delete=models.CASCADE, blank=True, null=True) class Employer(UserProfile): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='employerprofile', blank=True, null=True) company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='employercompany', blank=True, null=True, unique=True) # departments = models.ManyToManyField('Department', blank=True, related_name="members") # class Meta: # unique_together = ["id", "company"] class Employee(UserProfile): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='employeeprofile', blank=True, null=True) company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='employeecompany', blank=True, null=True) departments = models.ManyToManyField(Department, blank=True) employer = TenantForeignKey(Employer, on_delete=models.PROTECT, blank=True, null=True) reg_id = models.CharField(max_length=255, blank=True, null=True) role = TenantForeignKey("company.Role", on_delete=models.PROTECT, blank=True, null=True) leave_day = TenantForeignKey("company.LeaveDays", on_delete=models.PROTECT, blank=True, null=True) identidication_type = models.CharField(max_length=255, blank=True, null=True) passport = models.CharField(max_length=255, blank=True, null=True) identidication = models.CharField(max_length=255, blank=True, null=True) employment_type = models.CharField(max_length=255, blank=True, null=True) known_as = models.CharField(max_length=255, blank=True, null=True) gender = models.CharField(max_length=255, blank=True, null=True) date_of_birth = models.DateField( blank=True, null=True) blood_group = models.CharField(max_length=255, blank=True, null=True) genotype = models.CharField(max_length=255, blank=True, null=True) employee_photo = models.FileField(upload_to='assets/',blank=True, null=True) start_date = models.DateField( blank=True, null=True) reports_to = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reportperson', blank=True, null=True) additional_reports = models.FileField(upload_to='assets/%d',blank=True, null=True) job_role = models.CharField(max_length=255, blank=True, null=True) salary = models.FloatField( blank=True, null=True) daily_cost_of_absence = models.FloatField( blank=True, null=True) nationality = models.CharField(max_length=255, blank=True, null=True) def get_full_name(self): return self.user.first_name+" "+self.user.last_name def __str__(self): return self.user.username
After creating migrations, when i try ti migrate, I get this error
django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table «users_employer»
Kindly look into it for me.
See more:
CREATE TABLE INVENTORY( machine_name VARCHAR(25) UNIQUE, --ip_address WILL NEVER BE LONGER THAN 15 CHARACTERS BASED OF THE IP ADDRESS FORMAT ip_address CHAR(15) NOT NULL, --network_port WILL NEVER BE LONGER THAN 6 CHARACTERS BASED OF THE NETWORK PORT FORMAT network_port CHAR(6) NOT NULL, --mac_address WILL NEVER BE LONGER THAN 17 CHARACTERS BASED OF THE MAC ADDRESS FORMAT mac_address CHAR(17) NOT NULL, location_id VARCHAR(3) NOT NULL, CONSTRAINT pk_INVENTORY PRIMARY KEY(machine_name,ip_address, network_port, mac_address), CONSTRAINT fk_INVENTORY FOREIGN KEY (location_id) REFERENCES LOCATIONS(location_id) ON DELETE CASCADE ON UPDATE CASCADE ); CREATE TABLE TICKETS( ticket_number INT, owner_pplSoft INT NOT NULL, date_submitted DATE NOT NULL, date_closed DATE NOT NULL, --DATEDIFF() WILL BE USED HERE TO GET THE INT VALUE days_worked_on INT NOT NULL, category_id INT NOT NULL, machine_name VARCHAR(25) NOT NULL, location VARCHAR(10) NOT NULL, description VARCHAR(280), CONSTRAINT pk_TICKETS PRIMARY KEY(ticket_number), CONSTRAINT fk_1_TICKETS FOREIGN KEY (owner_pplSoft) REFERENCES USERS(pplSoft) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_2_TICKETS FOREIGN KEY (category_id) REFERENCES CATEGORIES(category_id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_3_TICKETS FOREIGN KEY (machine_name) REFERENCES INVENTORY(machine_name) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_4_TICKETS FOREIGN KEY (location) REFERENCES LOCATIONS(location) ON DELETE CASCADE ON UPDATE CASCADE );
What I have tried:
i tried adding the unique constraint to the variable machine_name in the inventory relation.
Comments
1 solution
Solution 1
The error message means one of your foreign key constraints is referencing a field that is not unique. For example you have:
CONSTRAINT fk_4_TICKETS FOREIGN KEY (location) REFERENCES LOCATIONS(location) ON DELETE CASCADE ON UPDATE CASCADE
That foreign key references the location field in the LOCATIONS table. However, the location field is not unique (either with a unique constraint or as a primary key) so the foreign key cannot be created.
This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
Top Experts | |
Last 24hrs | This month |
CodeProject,
20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8
+1 (416) 849-8900
StackOverflow All rights reserved. 93 / 83 / 24 Регистрация: 03.08.2013 Сообщений: 258 |
||||
1 |
||||
07.12.2013, 21:15. Показов 22750. Ответов 10 Метки нет (Все метки)
Замучила.
Я с SQL только знакомлюсь, много ещё не знаю. Учусь по манам. С утра сижу, может поэтому не соображаю уже, где тут ошибка. Ах да, СУБД — PostgreSQL.
__________________
0 |
1562 / 1040 / 94 Регистрация: 17.04.2009 Сообщений: 2,995 |
|
07.12.2013, 21:42 |
2 |
Ошибка «There is no unique constraint matching given keys for referenced table» Ну тут же русским по белому написано — нужен констрейнт на уникальность на пару products(product_name, price)
0 |
All rights reserved. 93 / 83 / 24 Регистрация: 03.08.2013 Сообщений: 258 |
|
07.12.2013, 21:50 [ТС] |
3 |
KuKu, да перевести то я в состоянии, я не могу понять, какое/-ие ограничение/-я на уникальность то нужны? Что с кодом не так?
0 |
1562 / 1040 / 94 Регистрация: 17.04.2009 Сообщений: 2,995 |
|
07.12.2013, 21:52 |
4 |
0 |
All rights reserved. 93 / 83 / 24 Регистрация: 03.08.2013 Сообщений: 258 |
|
07.12.2013, 21:55 [ТС] |
5 |
KuKu, я эту главу перечитал уже раз -дцать. Вы видите ошибку?
0 |
1562 / 1040 / 94 Регистрация: 17.04.2009 Сообщений: 2,995 |
|
07.12.2013, 21:58 |
6 |
KuKu, я эту главу перечитал уже раз -дцать. Вы видите ошибку? Ну можно прочитать -дцать первый. Создайте unique constraint на поля (product_name, price) в таблице products
1 |
All rights reserved. 93 / 83 / 24 Регистрация: 03.08.2013 Сообщений: 258 |
|
07.12.2013, 22:15 [ТС] |
7 |
Из всего этого я вынес, что ссылаться можно на колонку/-и, содержащую/-ие уникальные данные. Верно?
0 |
1562 / 1040 / 94 Регистрация: 17.04.2009 Сообщений: 2,995 |
|
07.12.2013, 22:17 |
8 |
Да.
1 |
All rights reserved. 93 / 83 / 24 Регистрация: 03.08.2013 Сообщений: 258 |
|
07.12.2013, 22:25 [ТС] |
9 |
KuKu, а если сослаться просто на айдишник, как тогда проверить, что наименование товара в первой и во второй таблице совпадают? Скажем, заплонил я первую таблицу некоторыми строками с наименованием товара и ценой, а при заполнении второй таблицы я либо допустил ошибку и добавил неверное имя, либо намеренно добавил товар, которого нет в списке в первой таблице. Возникновение противоречивости данных, хранящихся в базе, разве не так? Я, конечно же, допускаю, что могу не понимать принципа работы подобных механизмов. Если я в чём-то ошибаюсь, поправьте пожалуйста.
0 |
1562 / 1040 / 94 Регистрация: 17.04.2009 Сообщений: 2,995 |
|
07.12.2013, 22:32 |
10 |
Ну я не могу ничего советовать, пока не знаю что вы хотите хранить — но чаще всего так неверно.
кажем, заплонил я первую таблицу некоторыми строками с наименованием товара и ценой, а при заполнении второй таблицы я либо допустил ошибку и добавил неверное имя, либо намеренно добавил товар Для того, чтобы не было ошибок и надо заполнять в одном месте. А в другом месте указать айдишник — и по айдишнику мы достаем однозначное значение имени и цены. Без какого-нибудь словесного описания структуры сложно говорить конкретнее. Да и люди наверное книги про это пишут — в пост явно не уложиться
1 |
All rights reserved. 93 / 83 / 24 Регистрация: 03.08.2013 Сообщений: 258 |
|
07.12.2013, 22:49 [ТС] |
11 |
KuKu, если вам интересно, чего я пытаюсь добиться, то вот вам ссылка на тему, в которой, к сожалению, так пока никто и не отписался. В ней я подробно изложил суть ТЗ. С базами данных раньше дел не имел, поэтому приходится и проектом заниматься, и разбираться одновременно. Буду очень рад любому совету
0 |
You can’t disable a foreign key constraint in Postgres, like you can do in Oracle. However, you can remove the foreign key constraint from a column and then re-add it to the column.
Here’s a quick test case in five steps:
- Drop the
big
andlittle
table if they exists. The firstdrop
statement requires a cascade because there is a dependentlittle
table that holds a foreign key constraint against the primary key column of thebig
table. The second drop statement does not require the cascade keyword because there is not a dependent foreign key constraint.DROP TABLE IF EXISTS big CASCADE; DROP TABLE IF EXISTS little;
- Create the
big
andlittle
tables:-- Create the big table. CREATE TABLE big ( big_id SERIAL , big_text VARCHAR(20) NOT NULL , CONSTRAINT pk_little_1 PRIMARY KEY (big_id)); -- Display the big table. d big -- Create little table. CREATE TABLE little ( little_id SERIAL , big_id INTEGER NOT NULL , little_text VARCHAR(20) NOT NULL , CONSTRAINT fk_little_1 FOREIGN KEY (big_id) REFERENCES big (big_id)); -- Display the little table. d little
If you failed to designate the
big_id
column as a primary key constrained, Postgres will raise the following exception:ERROR: there IS no UNIQUE CONSTRAINT matching given KEYS FOR referenced TABLE "big"
- Insert a non-compliant row in the
little
table. An insert statement into thelittle
table with a value for the foreign key column that does not exist in thebig_id
column of thebig
table would fail with the following error:ERROR: INSERT OR UPDATE ON TABLE "little" violates FOREIGN KEY CONSTRAINT "fk_little_1" DETAIL: KEY (big_id)=(2) IS NOT present IN TABLE "big".
Re-enabling the foreign key constraint, the insert statement succeeds after you first insert a new row into the
big
table with the foreign key value for thelittle
table as its primary key. The following two insert statements add a row to both thebig
andlittle
table:-- Insert into a big table. INSERT INTO big (big_text) VALUES ('Cat in the Hat 2'); -- Insert into a little table. INSERT INTO little (big_id ,little_text) VALUES ( 2 ,'Thing 3');
Then, you can query it like this:
SELECT * FROM big b JOIN little l ON b.big_id = l.big_id;
big_id | big_text | little_id | big_id | little_text --------+------------------+-----------+--------+------------- 1 | Cat IN the Hat 1 | 1 | 1 | Thing 1 1 | Cat IN the Hat 1 | 2 | 1 | Thing 2 2 | Cat IN the Hat 2 | 3 | 2 | Thing 3 (3 ROWS)
- You can drop a foreign key constraint with the following syntax:
ALTER TABLE little DROP CONSTRAINT fk_little_1;
- You can add a foreign key constraint with the following syntax:
ALTER TABLE little ADD CONSTRAINT fk_little_1 FOREIGN KEY (big_id) REFERENCES big (big_id);
As always, I hope this helps you solve problems.