Can't create foreign key on another table using ID of my users table [Foreign key constraint is incorrectly formed] - migration

I was trying to create a comments table that was going to have a foreign key user_id that refferenced the "ID" on users table. But each time I ran my migration, I kept getting this error.
SQLSTATE[HY000]: General error: 1005 Can't create table 9anime.comments (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table comments add constraint comments user_id foreign foreign key (user_id) references users (id) on delete cascade)
My users migration code
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
My comments migration file
Schema::table('comments', function (Blueprint $table) {
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
});
When I run my migration, I get that error. I looked at my code and did not find anything wrong with it.
This answer suggested that the user_id be made nullable. I did that but it did not change anything

I edited the users migration file, specifically this line
$table->id();
to
$table->increments('id');
then ran my migration and it worked

Related

How to Change Asp.net Core Identity AspNetUsers Role Primary key Data Type

I am trying to change the Data Type of .NET core Identity AspNetUsers primary key data type from GUID to Int. but couldn't find a way. What can I do to change only AspNetUsers primary key data type.
on model creating event
modelBuilder.Entity<ApplicationUser>(b =>
{
// Primary key
b.HasKey(u => u.Id).HasColumnType("int");
//other configuration
});
then run in package manager console
Run Update-Database

How to add a conditional unique constraint in Liquibase?

Problem: When a user is deleted the associated record is not deleted from the database. Instead, I set user.delete column to true. Now I need to put a unique constraint on user.email but only for active users (not deleted).
How can I do this?
databaseChangeLog:
- changeSet:
id: add-user-unique-constraint
author: me
changes:
- addUniqueConstraint:
columnNames: email, delete
constraintName: unique-email-not-deleted
tableName: users
The above naive approach puts a composite constraint on (email, delete) columns, but it doesn't work because in the following flow user is blocked from deleting and creating an account:
register a new user with email "E"
delete the user with email "E"
register again new user with email "E"
delete the user with email "E" -> error: constraint violation
register new user with email "E" -> error: constraint violation
ps. databases are H2 and PostgreSQL
This feature is DB-specific and currently liquibase doesn't support it.
For PostgreSQL you may use direct SQL:
databaseChangeLog:
- changeSet:
id: add-user-unique-constraint
author: me
changes:
- sql:
"sql": "CREATE UNIQUE INDEX user_email_idx ON user (email) WHERE delete = 'false'"
however this will NOT work in H2.
Possible options for H2:
if it's used in tests then you may migrate to PostgreSQL using testcontainers technology (but your build environment will depend on docker)
have custom changesets for PostgreSQL and H2 - you may use preconditions

POSTGRES - Risk of dropping foreign data wrapper/schema

We had one of the devs create a foreign data wrapper with these commands:
CREATE SERVER serverName FOREIGN DATA WRAPPER postgres_fdw OPTIONS (xxxx);
CREATE USER MAPPING FOR user SERVER foreign_db OPTIONS (user 'xxxx', password 'xxxx');
CREATE SCHEMA foreign_db;
IMPORT FOREIGN SCHEMA public FROM SERVER serverName INTO foreign_db;
To drop this schema the suggestion was to run:
DROP SCHEMA if exists foreign_db cascade;
DROP USER mapping if exists for user server foreign_db;
DROP SERVER if exists serverName;
In the spec I see this for CASCADE:
Automatically drop objects (tables, functions, etc.) that are
contained in the schema, and in turn all objects that depend on those
objects
what concerns me is this line:
and in turn all objects that depend on those objects
My question is there a possibility of dropping anything outside of foreign_db schema and if yes, how can I check it?
Thank you.
It is possible that the command drops something outside the schema. Consider this:
create schema example;
create table example.my_table (id int);
create view public.my_view as select * from example.my_table;
If the schema is dropped with the cascade option, public.my_view will also be dropped. However, the behavior is logical and desirable.
You can check this executing these commands one by one:
begin;
drop schema example cascade;
rollback;
The schema will not be dropped and after drop... you should get something like this:
NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table example.my_tabledrop cascades to view my_view
Alternatively, you can use the system catalog pg_depend, see this answer How to list tables affected by cascading delete.

SQL Server : permissions to allow disable/reenable FK constraint, but no other alter

Are there permission settings that will allow a principal to disable/enable a foreign key constraint, but not allow other table alteration?
E.g.: from a 'dbo' principal:
create login ref_test with password = 'test1234'
create user ref_test
exec sp_addrolemember 'db_datareader', 'ref_test'
exec sp_addrolemember 'db_datawriter', 'ref_test'
create table A (ID int not null, constraint PK_A primary key (ID))
create table B (Aid int not null, constraint FK_Aid_AID foreign key (Aid) references A(ID))
From a ref_test login-connection:
insert A values (1)
insert B values (1)
Now, I need to be able to update the key in the FK relationship, like so:
-- will fail
ALTER TABLE B NOCHECK CONSTRAINT FK_Aid_AID
update A set ID = ID + 1
update B set AID = AID + 1
ALTER TABLE B WITH CHECK CHECK CONSTRAINT FK_Aid_AID
This fails with
Msg 1088, Level 16, State 13, Line ...
Cannot find the object "B" because it does not exist or you do not have permissions
If I add
GRANT ALTER on B to ref_test
It will work, but not without also enabling ALTER TABLE B DROP CONSTRAINT FK_Aid_AID, as well as enabling other DDL on the table--add/drop columns, other constraints--though not allowing the FK in question to be re-added--that requires an additional GRANT REFERENCES (ID) on A to ref_test.
No, there's no way to do this with SQL Server's permission scheme. To perform any particular ALTER TABLE statement you need ALTER permission, and that in turn allows you to perform any ALTER TABLE statement whatsoever, save those that require updating columns or referencing external types or columns (which require separate rights).
One general way of granting accounts permission to do things they wouldn't otherwise be able to do (and only those things) is to encapsulate them in stored procedures that execute under privileged accounts. So let's say you want to give an account the ability to disable or enable any constraint on any table, but not to do anything else DDL-related with those tables:
CREATE PROCEDURE nocheck_constraint(#table SYSNAME, #constraint SYSNAME)
WITH EXECUTE AS OWNER AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQL NVARCHAR(MAX);
SET #SQL = REPLACE(REPLACE(
'ALTER TABLE $table NOCHECK CONSTRAINT $constraint;',
'$table', QUOTENAME(#table)),
'$constraint', QUOTENAME(#constraint))
;
PRINT #SQL;
EXEC(#SQL);
END;
GO
-- The following is necessary only for direct calls.
-- Note that ownership chaining will allow *any* stored procedure to call this one without
-- a separate permission check, which is a double-edged sword.
GRANT EXECUTE ON nocheck_constraint TO [unprivileged_account];
And similarly for check_constraint. Of course you can make this more fine-grained as you require.
I'm taking a potentially dangerous shortcut here by leveraging EXECUTE AS OWNER so I can do dynamic SQL without security restrictions. If you are not in full control of the database and all procedures created in it, this has some consequences for the security of not just the database, but the rest of the server as well. In that case, you may want to look into signing the procedure and using a proxy instead. Instead of hashing that all out here, I refer you to Erland Sommarskog's excellent writeup on the matter.
I have user(s) for which I wont to give permission in Management Studio to change extended properties for columns of table(s).
So when give ALTER permission on table for that user it can be seen Keys, Indexes, Constraint, even it can not be changed. So not to be seen there is DENY on SELECT in sys.check_constraint, sys.foreignkeys, sys.key_constraint ....
So maybe with ALTER ON tables and some combination of DENY and GRANT on sys.columns, sys.foreignkeys, sys.check_constraint....it is possible to allow a principal to disable/enable a foreign key constraint, but not allow other table alteration
Msg 1088, Level 16, State 13, Line ...
Cannot find the object "B" because it does not exist or you do not have permissions
if I do this with management studio, I notice next:
if I don't have SELECT permission on particular table it will be a problem, all ForeignKey will be disappear
If I don't have SELECT permission then in CheckExistingData on Creation or Enabling if it is yes it should be changed in No, and EnforceForeignKey Constraint can be changed from Yes to No, or opposite
So :
1. or SELECT permission on table (which is needed for CheckExistingDataOnCreatinon or Reanabling if it is set to Yes)
2. or CheckExistingDataOnCreation or Reanablig (creating again) set to No

Add same role in rights module gives me Integrity constraint violation error

I am currently working on rights module. i add trade_company_id in authitem table. so when different company add same role it should allowed. but it gives me Integrity constraint violation: 1062 Duplicate entry 'companyadmin' for key 'PRIMARY'. The SQL statement executed was: INSERT INTO authitem (name, type, description, bizrule, data) VALUES (:name, :type, :description, :bizrule, :data) Error.
What i should do?