So i wish to create the following 2 tables : user and user_address and have a 1:many relationship among them, i.e a user can have multiple addresses. I followed the sequelize docs and ran the .belongsTo and hasMany on the models of these 2 tables, but i can't seem to query them when i request for a all users with include=[{model:'user_address'}] filter. I wanted to create a scalable system, so i used a somewhat modular approach.
The tables are defined in different files as js objects:
//user.js
const { DataTypes} = require('sequelize');
const name = "user"
const model ={
email : {type:DataTypes.STRING, allowNull:false,unique:true},
password : {type:DataTypes.STRING(16), allowNull:false},
phone : {type:DataTypes.STRING(20), allowNull:true},
name : {type:DataTypes.STRING(50), allowNull:true},
birthday : {type:DataTypes.STRING(50), allowNull:true},
}
const initConfig = {freezeTableName: true}
const getInstance = (email, pwd, phone = null, name = null, dob = null)=>{
return {email: email, password: pwd, phone: phone, name: name, birthday: dob}
}
module.exports = {
name:name,
model:model,
config:initConfig,
getInstance:getInstance
}
//user_address.js
const {DataTypes} = require("sequelize");
const name = "user_address"
const model = {
address : {type:DataTypes.STRING, allowNull:false},
zipcode : {type:DataTypes.INTEGER, allowNull:false},
is_main_address : {type:DataTypes.BOOLEAN, allowNull:false, default:false},
address_alias : {type:DataTypes.STRING, allowNull:true},
address_phone_number : {type:DataTypes.STRING, allowNull:true},
city : {type:DataTypes.STRING, allowNull:true},
}
// user_id : {type:DataTypes.INTEGER, allowNull:true, references: {model: 'user', key: 'id',},}
const config = {
freezeTableName: true
}
module.exports = {
name:name,
model:model,
config:config,
getInstance:()=>{},
}
then we have this ModelKeys.js class that provides an easy access to these model schemas:
const user = require("./user");
const note = require("./note");
const user_address = require('./user_addresses')
module.exports = {
ModelNames:{
USER : user,
USER_ADDRESS: user_address,
NOTE: note,
}
}
then we have this init db class that is supposed to initialise db, define models and run associations on them
const {Sequelize} = require('sequelize');
const {db_creds} = require("../.secrets/db_secrets");
const {ModelNames} = require("./models/model_keys");
const {logDB} = require("../a_commons/logutils");
let db = undefined
async function initTables() {
// create tables
Object.keys(ModelNames).forEach(key=>{
let model = ModelNames[key]
try {
logDB("initialising MODEL=",model==null? "null": `{js_obj : ${model.name}}`)
db.define(model.name,model.model,model.config)
logDB(`model created successfully : ${model.name}` )
}
catch (e) {logError(e)}
})
//sync with dbms
logDB("initialising sync with dbms server...")
await db.sync()
logDB("models synced successfully")
}
function validateTables() {
logDB("all tables are created.","tables=",db.models)
}
async function runAssociations(){
//create associations
logDB("init associations")
let userTable = db.models[ModelNames.USER.name]
let userAddressTable = db.models[ModelNames.USER_ADDRESS.name]
await userTable.hasMany(userAddressTable)
await userAddressTable.belongsTo(userTable)
logDB("associations created successfully")
//sync with dbms
logDB("initialising sync with dbms server...")
await db.sync()
logDB("models synced successfully")
}
module.exports = {
MyDatabase:{
initDB : async () => {
db = new Sequelize(db_creds)
await db
.authenticate()
.then(_ => logDB('Connection established successfully.'))
.then(_ => initTables())
.then(_ => validateTables())
.then(async _ => (await runAssociations()))
.catch(error => logError('Something went wrong', error))
},
getDB: ()=> {
// only useful once initDB is called
return db;
},
getTable : (modelName) => {
// only useful once initDB is called
return db.models[modelName]
}
}
}
if you notice, i did not created any identifier primary keys for my tables but since sequelize automatically generates id key, i was expecting the tables to get created successfully, which they do. during runAssociations() , function, i was also not sure, if it would work since the tables have already been created, and neither table has any reference to them, but i expected this to work.
this whole file runs when someone calls MyDatabase.initDB() and it runs without any errors.
therefore i further created a user_repo.js which looks like this :
const {MyDatabase} = require("./init_db");
const {ModelNames} = require("./models/model_keys");
const {logRepo} = require("../a_commons/logutils");
let userTable = null
module.exports = {
UserRepo: {
initDatabase: async () => {await MyDatabase.initDB()},
init: () => {
userTable = MyDatabase.getTable(ModelNames.USER.name)
logRepo("table initialised. table=",userTable.name)
},
createUser: async (user) => {
await userTable
.create(user)
.then(it => logRepo("user build successfully!", it.toJSON()))
},
getAllUsers: async () => {
let users = await userTable.findAll({include:[{model:MyDatabase.getTable(ModelNames.USER_ADDRESS.name)}]})
logRepo("available users = ", users.map(it=>it.email))
return users
},
getSingleUser: async (email) =>{
return await userTable.findOne(
{where: {email: email}, include:[{model:MyDatabase.getTable(ModelNames.USER_ADDRESS)}]},
)
}
}
}
however, when i run these lines:
const {UserRepo} = require("./user_repo");
const {ModelNames} = require("./models/model_keys");
async function x(){
let repo = UserRepo
await repo.initDatabase()
await repo.init()
await repo.createUser(ModelNames.USER.getInstance("ansh#12345.com","12345678"))
await repo.getAllUsers()
}
x()
1st few lines run perfectly, but for getAllUsers() line ,i get this error :
Executing (default): SELECT "user"."id", "user"."email", "user"."password", "user"."phone", "user"."name", "user"."birthday", "user"."createdAt", "user"."updatedAt", "user_addresses"."id" AS "user_addresses.id", "user_addresses"."address" AS "user_addresses.address", "user_addresses"."zipcode" AS "user_addresses.zipcode", "user_addresses"."is_main_address" AS "user_addresses.is_main_address", "user_addresses"."address_alias" AS "user_addresses.address_alias", "user_addresses"."address_phone_number" AS "user_addresses.address_phone_number", "user_addresses"."city" AS "user_addresses.city", "user_addresses"."createdAt" AS "user_addresses.createdAt", "user_addresses"."updatedAt" AS "user_addresses.updatedAt", "user_addresses"."userId" AS "user_addresses.userId" FROM "user" AS "user" LEFT OUTER JOIN "user_address" AS "user_addresses" ON "user"."id" = "user_addresses"."userId";
node:internal/process/promises:265
triggerUncaughtException(err, true /* fromPromise */);
^
Error
at Query.run (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/sequelize/lib/dialects/postgres/query.js:50:25)
at /Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/sequelize/lib/sequelize.js:314:28
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async PostgresQueryInterface.select (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/sequelize/lib/dialects/abstract/query-interface.js:407:12)
at async Function.findAll (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/sequelize/lib/model.js:1134:21)
at async Object.getAllUsers (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/db/user_repo.js:22:25)
at async x (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/db/test_io.js:101:5) {
name: 'SequelizeDatabaseError',
parent: error: column user_addresses.userId does not exist
at Parser.parseErrorMessage (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/parser.js:287:98)
at Parser.handlePacket (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/parser.js:126:29)
at Parser.parse (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/parser.js:39:38)
at Socket.<anonymous> (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/index.js:11:42)
at Socket.emit (node:events:520:28)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Socket.Readable.push (node:internal/streams/readable:228:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
length: 120,
severity: 'ERROR',
code: '42703',
detail: undefined,
hint: undefined,
position: '839',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '3643',
routine: 'errorMissingColumn',
sql: 'SELECT "user"."id", "user"."email", "user"."password", "user"."phone", "user"."name", "user"."birthday", "user"."createdAt", "user"."updatedAt", "user_addresses"."id" AS "user_addresses.id", "user_addresses"."address" AS "user_addresses.address", "user_addresses"."zipcode" AS "user_addresses.zipcode", "user_addresses"."is_main_address" AS "user_addresses.is_main_address", "user_addresses"."address_alias" AS "user_addresses.address_alias", "user_addresses"."address_phone_number" AS "user_addresses.address_phone_number", "user_addresses"."city" AS "user_addresses.city", "user_addresses"."createdAt" AS "user_addresses.createdAt", "user_addresses"."updatedAt" AS "user_addresses.updatedAt", "user_addresses"."userId" AS "user_addresses.userId" FROM "user" AS "user" LEFT OUTER JOIN "user_address" AS "user_addresses" ON "user"."id" = "user_addresses"."userId";',
parameters: undefined
},
original: error: column user_addresses.userId does not exist
at Parser.parseErrorMessage (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/parser.js:287:98)
at Parser.handlePacket (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/parser.js:126:29)
at Parser.parse (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/parser.js:39:38)
at Socket.<anonymous> (/Users/anshsachdeva/Downloads/f1_self/f4_web/f4_web_individual_gits/ecommerce/sequalize_tests/notes_db/node_modules/pg-protocol/dist/index.js:11:42)
at Socket.emit (node:events:520:28)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Socket.Readable.push (node:internal/streams/readable:228:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
length: 120,
severity: 'ERROR',
code: '42703',
detail: undefined,
hint: undefined,
position: '839',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '3643',
routine: 'errorMissingColumn',
sql: 'SELECT "user"."id", "user"."email", "user"."password", "user"."phone", "user"."name", "user"."birthday", "user"."createdAt", "user"."updatedAt", "user_addresses"."id" AS "user_addresses.id", "user_addresses"."address" AS "user_addresses.address", "user_addresses"."zipcode" AS "user_addresses.zipcode", "user_addresses"."is_main_address" AS "user_addresses.is_main_address", "user_addresses"."address_alias" AS "user_addresses.address_alias", "user_addresses"."address_phone_number" AS "user_addresses.address_phone_number", "user_addresses"."city" AS "user_addresses.city", "user_addresses"."createdAt" AS "user_addresses.createdAt", "user_addresses"."updatedAt" AS "user_addresses.updatedAt", "user_addresses"."userId" AS "user_addresses.userId" FROM "user" AS "user" LEFT OUTER JOIN "user_address" AS "user_addresses" ON "user"."id" = "user_addresses"."userId";',
parameters: undefined
},
sql: 'SELECT "user"."id", "user"."email", "user"."password", "user"."phone", "user"."name", "user"."birthday", "user"."createdAt", "user"."updatedAt", "user_addresses"."id" AS "user_addresses.id", "user_addresses"."address" AS "user_addresses.address", "user_addresses"."zipcode" AS "user_addresses.zipcode", "user_addresses"."is_main_address" AS "user_addresses.is_main_address", "user_addresses"."address_alias" AS "user_addresses.address_alias", "user_addresses"."address_phone_number" AS "user_addresses.address_phone_number", "user_addresses"."city" AS "user_addresses.city", "user_addresses"."createdAt" AS "user_addresses.createdAt", "user_addresses"."updatedAt" AS "user_addresses.updatedAt", "user_addresses"."userId" AS "user_addresses.userId" FROM "user" AS "user" LEFT OUTER JOIN "user_address" AS "user_addresses" ON "user"."id" = "user_addresses"."userId";',
parameters: {}
}
Process finished with exit code 1
Any idea on how to fix this?
You need to register all models and all their associations before calling sync because hasMany/belongsTo only registers associations inside Sequelize models do nothing in DB. Its the responsibility of sync to create the whole structure taking into account all registered models and associations.
await db
.authenticate()
.then(_ => logDB('Connection established successfully.'))
.then(_ => runAssociations())
.then(_ => initTables())
.then(_ => validateTables())
.catch(error => logError('Something went wrong', error))
I have a script reads data from a json file and inserts them into postgres. Well, that's what it's supposed to do.
The json is read properly and I can see the data as an array in the variables. The connection is made to postgres successfully.
Then I get this error:
syntax error at or near "'{"Archived":"false","ClientEmail":"imaclientcompany#gmail.com","ClientId":52,"ClientName":"Ima Client","DateCreated":1637074825658,"DateSubmitted":1637076927912,"ExternalClientId":"null","Id":"8b9391c0-00af-4710-9481-e0e33ddea546","Practitioner":"bob#jonesperformancecenter.com","PractitionerId":"57b49e3d12cd2f144cebb405","PractitionerName":"Bob Jones","QuestionnaireId":"612524e13ccc040f58dd134e","QuestionnaireName":"PTS Pre Session Form","Status":"Completed"}'" at character 224.
The details of the error:
length: 566,
severity: 'ERROR',
code: '42601',
detail: undefined,
hint: undefined,
position: '224',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'scan.l',
line: '1145',
routine: 'scanner_yyerror'
Character 224 is in the middle of the Id field.
The 42601 error is a syntax with no hint or detail. When I google 'scanner_yyerror' all the hits refer to unescaped single quotes. There are no single quotes in the data.
Here is the script:
const pg = require('pg');
const { Pool } = require('pg');
const format = require('pg-format');
const fs = require('fs');
let rawintakes = fs.readFileSync('./data/intakes.json', 'utf8');
let intakes = JSON.parse(rawintakes);
let query1 = format('INSERT INTO intake_summary (Archived, ClientEmail, ClientId, ClientName, DateCreated, DateSubmitted, ExternalClientId, Id, Practitioner, PractitionerId, PractitionerName, QuestionnaireId, QuestionnaireName, Status) VALUES %L returning id', intakes);
async function run() {
let client;
try {
client = new pg.Pool({
connectionString: 'postgres://postres:reallystrongpassword#localhost:5432/cldba01'
});
await client.connect();
let {rows} = await client.query(query1, intakes);
console.log(rows);
} catch (e) {
console.error(e);
} finally {
client.end();
}
}
run();
I can input the same data using SQL without a problem. I have deleted the first record and the same problem occurs on the second one at the same position 224.
I've looked at the query and I don't see a syntax error there either.
Any ideas?
My advice is to use SEQUELIZE instead of SQL , it is far easier and more clear.
I have a sqlite database and with the programm sqliteStudio I can connect and save things. My Problem is the connection to the database with node.js with the npm package "sqlite". Every time I want to do a query it can't find the table. My code:
const connection = await sqlite.open('./db.sqlite');
const data = await connection.run("select * from item")
After that with console.log(connection), I get the following message with looks good in my opinion
driver: Database { open: true, filename: './db.sqlite', mode: 65542 },
Promise: [Function: Promise] }
But the output of console.log(data) is always a error message:
{ Error: SQLITE_ERROR: no such table: item errno: 1, code: 'SQLITE_ERROR' }
I think it is a problem with async/await or with my .sqlite file but I don't know
you are right, you have to use the arrow-function to wait until database is open, see here:
// database is not existing
console.log('open database and create table');
db = new sqlite3.Database('./event.db',() => {
db.run('CREATE TABLE logTable(logfile TEXT,logdate TEXT,referto TEXT, area TEXT,status TEXT,action TEXT)',() => {
...
});
// if db is existing
db = new sqlite3.Database('./event.db'() => {
...
});
I'm trying to insert a map type in cassandra:
const query = 'INSERT INTO stats.tickets (office, line, generation, inserted_at, meta, number, prefix) VALUES (:office, :line, :generation, :inserted_at, :meta, :number, :prefix)';
const parametersExample = {
office: "office",
line: "line",
generation: 10,
inserted_at: Date.now(),
meta: {"tag1": "ujkukkik", "tag2": "asdascee"},
number: 1,
prefix: "prefix_"
};
const result = async () => {
return await client.execute(query, parametersExample, { prepare: true });
};
result().then( res => {
res.rows.map( row => console.log(row.content) );
process.exit();
}).catch( err => console.error(err));
The code insert the row but shows the following message:
TypeError: Cannot read property 'map' of undefined
at lib/handleData.js:23:14
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
What is the reason?
That's normal behavior - per CQL documentation:
INSERT returns no results unless IF NOT EXISTS is used.
So driver receives undefined... Usually .map will be used for selects.
I have a database goods with two columns id jsonb primary_key and name.
Using this query:
const query = 'INSERT INTO "goods" (id, name) VALUES ($1, $2)'
together with the following data:
const data = {id: 1, name: "milk"};
gives me the following error:
{ [error: bind message supplies 1 parameters, but prepared statement "" requires 2]
name: 'error',
length: 130,
severity: 'ERROR',
code: '08P01',
detail: undefined,
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'postgres.c',
line: '1556',
routine: 'exec_bind_message' }
I have a postgres database set up, connected via pg.Pool() and executing javascript to insert my data.
Edit:
This is how I prepare my query:
pool.query(query, [data]).then(() => {
console.log("ok")
})
.catch(error => {
console.log(error)
});
Edit2:
Using the following:
const query = 'INSERT INTO "goods" (id, name) VALUES ($1, $2)'
const data = JSON.stringify([1, "milk"]);
pool.query(query, data).then(() => {
console.log("ok")
})
.catch(error => {
console.log(error)
});
Just spits out the following error: [TypeError: self.values.map is not a function]
As per docs, parameters must be JavaScript object (which is array). So you don't need to stringify data
Try this:
const query = 'INSERT INTO goods (id, name) VALUES ($1, $2)'
const data = [1, "milk"];
pool.query(query, data).then(....)
Or
pool.query({
text: 'INSERT INTO goods (id, name) VALUES ($1, $2)',
values: [1, 'milk']
}).then(...)
As per documentation, a Prepared Statement expects an array of values, not an object with properties, i.e. your data must be: const data = [1, "milk"];
I had the same problem using slonik.
Don't use interpolation
Don't do this!
connection.query(sql`
SELECT 1
FROM foo
WHERE bar = ${baz}
`);
Use value placeholders
Do this - wrap variable with single quote
connection.query(sql`
SELECT 1
FROM foo
WHERE bar = ${'baz'}
`);