Seed with relation in knex - postgresql

Hi guys I'm trying to seed my data with knex and knex cli
I have 2 models: User & User Profile
User
CREATE TABLE users(
id SERIAL PRIMARY KEY NOT NULL,
name TEXT,
screenname TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
)
User Profile
CREATE TABLE userProfile(
email TEXT,
password TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_id INTEGER,
PRIMARY KEY (user_id),
FOREIGN KEY (user_id) REFERENCES users (id)
)
Note that user Profile points to User and its 1:1 relationship
Os I'm trying to insert my users and along with that, to insert their profile data
I have created seed file like this:
exports.seed = function(knex) {
// Deletes ALL existing entries
return knex('users').del()
.then(function () {
return knex('userprofile').del();
})
.then(() => {
return knex('authenticationproviders').del();
})
.then(function () {
return knex('users')
.insert([
{
name: 'john',
screenname: 'admin'
},
{
name: 'stephan',
screenname: 'maras'
},
])
})
.then(function (users) {
// here insert profile info about user
// but user param doesn't contain userIds that are created
})
};
Here is how my profiles array looks:
[{
email: 'test#gmail.com',
user_id: 1, // this should be from existing user
password: 'pass1'
},
{
email: 'test2#gmail.com',
user_id: 2, // this should be from existing user that was created
password: 'pass2'
}]
Is there anyway how can I get userId from existing user, since users param is does not contain array of created users ??

Related

Add aditional user information when signup supabase

I am trying to add additional data in a user record in supabase, I have created a trigger that is called after a record has been inserted in auth user that should add the user id and username in the profiles table. This happens but it doesn't add the user name, it's still null in the profiles table. That data is supposed to go in the raw_user_meta_data column but it still doesn't add in the column
Trigger function:
BEGIN
INSERT INTO public.profiles(id, username)
VALUES (
NEW.id,
NEW.raw_user_meta_data -> 'username'
);
RETURN NEW;
END;
Front:
const createNewUser = async() => {
const { username, email, password } = credentials;
await supabase.auth.signUp({
email: email,
password: password,
data: {
"username": 'hello'
}
});
}
Just to follow up. Maybe this is the change with supabase v2 and supabasejs update, but now it seems to work with one argument, but slightly different than you had it in first post. Here is the link:
https://supabase.com/docs/reference/javascript/auth-signup#sign-up-with-additional-user-metadata
and the code:
const { data, error } = await supabase.auth.signUp({
email: userEmail.value,
password: password,
options: {
data: {
user_name: userName.value,
},
},
});
I found the solution reading over there, in case it helps anyone. My mistake was that in the signUp function I passed only 1 argument that had included the additional data that would be included in the trigger function. However, this signUp function must be passed 2 objects as arguments and it is this second argument that is passed that saves the object with the username extracted from the function in the front in the raw_user_meta_data column.
As additional data that can help you in the search for the error. You can know what the logs of the authentication process print. You can also insert a record directly in auth.users so you can see why it does not add additional data and be able to review the logs, I attach an example:
insert into auth.users(id, email, encrypted_password, raw_user_meta_data)
values (
'eb23060d-71ea-4112-a1c7-203d6f87fa2d',
'example#mail.com',
'$2y$10$WpAA2remsZRnZivgRaM9L.1BcjvAtUa966AICxv1RGte68BICsZkS',
'{"username": "user_example"}'
)
Final solution:
const { user, session, error } = await supabase.auth.signUp(
{
email: 'example#email.com',
password: 'example-password',
},
{
data: {
username: 'John'(variable)
}
}
)

knex / postgresql updating a foreign key to null

I am using knex.js with postgresql
So I have a table with a nullable foreign key.
shortened version:
exports.up = function (knex, Promise) {
return knex.schema.createTable('Note', function (table) {
table.string('id').primary()
table
.string('sourceId')
.references('id')
.inTable('Source')
.onDelete('SET NULL')
.index()
})
}
exports.down = function (knex, Promise) {
return knex.schema.dropTable('Note')
}
I am able to create a Note with or without a sourceId. However, if I create a Note with a sourceId and then update it to set the sourceId to NULL, the update does not work. I do not get an error message, but the foreign key is not removed.
For example if I create a Note with:
{
id: '123',
sourceId: '456'
}
and then try to update it:
const result = await Note.query().updateAndFetchById(id, {
id: '123',
sourceId: null
})
The result I get is :
Note {
id: '123',
sourceId: '456'
}
I have no problem if I try to update other nullable values to null (as long as they are not foreign keys) and I can update the sourceId to a different source's id.
If I try to update a not nullable foreign key to null, I get an error. But in the above case, I get no error. It just doesn't update.
Any idea what might be going on here?

Change primary key and its (foreign) references in existing table - Knex.js / Postgres

My Postgres DB has 2 tables, with thousands of rows each, that were initially created with the following migration:
exports.up = async function(knex, Promise) {
// users
await knex.schema.createTable('users', table => {
table.increments('id');
table.timestamps(false, true);
table.text('uid').notNullable().unique(),
table.text('email').notNullable();
table.text('password');
table.text('first_name').notNullable();
table.text('last_name').notNullable();
table.text('subscription_id');
table.boolean('is_active').notNullable().defaultTo(true);
table.boolean('is_blocked').notNullable().defaultTo(false);
table.enum('role', ['member', 'admin', 'test_user']).notNullable().defaultTo('member');
});
await knex.schema.raw('create unique index users_lower_email_index on users (lower(email))');
// projects
await knex.schema.createTable('projects', table => {
table.increments('id');
table.timestamps(false, true);
table.text('name').notNullable();
table.integer('user_id').notNullable().references('users.id').onDelete('cascade');
table.text('data');
});
};
I need to change the foreign key on the projects table so that it references the uid column instead from the users table.
The constraints on the users table are:
I tried the following migration but I get the error:
migration failed with error: alter table "users" add column "uid" text - column "uid" of relation "users" already exists
My code:
exports.up = async function(knex, Promise) {
await knex.schema.alterTable('users', table => {
table.text('uid').primary('users_pkey');
})
await knex.schema.alterTable('projects', table => {
table.text('user_id').notNullable().references('users.uid').onDelete('cascade').alter();
});
};
I also tried table.text('uid').primary('users_pkey').alter(); but then I get:
migration failed with error: alter table "users" add constraint "users_pkey" primary key ("uid") - multiple primary keys for table "users" are not allowed
I will transfer all users in auth0 and I though its better if I use a UUID primary key for the users table.
Before you can change the primary key of users, you need to remove the existing one, then you should be able to drop and recreate the foreign key in projects:
exports.up = async (knex) => {
await knex.schema.alterTable('users', (table) => {
table.dropPrimary()
table.primary('uid')
})
await knex.schema.alterTable('projects', (table) => {
table.dropForeign('user_id')
table.foreign('user_id').references('users.uid').onDelete('cascade')
})
}

How to insert data with explicit id property which has null value?

I have a js object with explicit id property. Like this:
const data = {
user_id: null,
user_email: faker.internet.email()
};
The value of user_id is null and there is a users table using user_id as its primary key.
I want to insert this data correctly and I hope knex can obey the primary key increment rule.
Here is my code:
async function insert(user: any) {
return await knex('users')
.insert(user)
.returning('*');
}
When I try to insert this data, got an error:
error: null value in column "user_id" violates not-null constraint
How can I solve this?
You can set the value of user_id to undefined. Then it will insert the data and
obey the primary key increment rule.
const data = {
user_id: undefined,
user_email: faker.internet.email()
};
Check the inserted row in users table. The value of user_id is 1

How to insert a record with id (auto increment) PostgREST?

I have a function
axios.post('http://localhost:3000/unitsmeasure', {
id: 20,
name: 'name'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
It inserts an entry in the table. Its works.
But when I do not specify the id it does not work. id (serial PRIMARY KEY).
axios.post('http://localhost:3000/unitsmeasure', {
name: 'name'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
This does not work
SQL Table:
CREATE TABLE "unitsmeasure" (
"id" serial PRIMARY KEY,
"name" varchar(100)
)
SQL Dump:
CREATE TABLE "unitsmeasure" (
"id" int8 NOT NULL DEFAULT nextval('"Request".unitsmeasure_id_seq'::regclass),
"name" varchar(100) COLLATE "pg_catalog"."default"
);
ALTER TABLE "unitsmeasure" OWNER TO "postgres";
ALTER TABLE "unitsmeasure" ADD CONSTRAINT "unitsmeasure_pkey" PRIMARY KEY ("id");
The most likely culprit is not having granted usage permissions to the sequence.
Try this:
GRANT USAGE ON SEQUENCE unitsmeasure_id_seq TO user_name;
The inserting user needs access to the sequence in order to insert a value from the sequence.