I’m fairly new at Postgresql and learning new things everyday. So I have this blog project where I want to use PostgreSQL as a db. But I’m kind of stuck at the most basic insert query which is throwing an error. I have three tables, posts
, authors
and categories
. I could create the table properly I guess but when I try to insert data I get this error:
error: syntax error at or near length: 95, severity: 'ERROR', code: '42601', detail: undefined, hint: undefined, position: '122', internalPosition: undefined, internalQuery: undefined, where: undefined, schema: undefined, table: undefined, column: undefined, dataType: undefined, constraint: undefined, file: 'scan.l', line: '1180', routine: 'scanner_yyerror'
Now I don’t know where the issue is and Postgres’ errors are not that specific.
Can anyone please tell me where I could be going wrong?
Here are the tables:
const createInitialTables = ` CREATE TABLE authors ( id UUID NOT NULL, author_name VARCHAR(100) NOT NULL UNIQUE CHECK (author_name <> ''), author_slug VARCHAR(100) NOT NULL UNIQUE CHECK (author_slug <> ''), PRIMARY KEY (id) ); CREATE TABLE posts ( id UUID NOT NULL, post VARCHAR(500) NOT NULL CHECK (post<> ''), post_slug VARCHAR(500) NOT NULL CHECK (post_slug <> ''), author_id UUID NOT NULL, PRIMARY KEY (id), CONSTRAINT fk_authors FOREIGN KEY(author_id) REFERENCES authors(id) ); CREATE TABLE categories ( id UUID NOT NULL, category_name VARCHAR(50) NOT NULL CHECK (category_name <> ''), category_slug VARCHAR(50) NOT NULL CHECK (category_slug <> ''), post_id UUID NOT NULL, PRIMARY KEY (id), CONSTRAINT fk_posts FOREIGN KEY(post_id) REFERENCES posts(id) ); `;
Here’s the async function where I’m making the insert query:
const insertAuthor = async() => { try { const data = await fs.readFile( path.join( __dirname + '../../data/data.json' ) ); const parsedData = JSON.parse( data.toString() ); const authorID = short.generate(); const authorName = parsedData[ 0 ].author; const authorSlug = slugify( parsedData[ 0 ].author, { strict: true, lower: true } ); const insertData = ` INSERT INTO authors (id, author_name, author_slug) VALUES (${authorID}, ${authorName}, ${authorSlug}); `; await pool.query( insertData ); console.log( 'Data inserted successfully!' ); } catch ( e ) { console.log( e ); } }; insertAuthor();
UPDATE————————————–
This is how the Postgres log file looks like:
2021-10-18 01:23:16.885 +06 [5964] ERROR: syntax error at or near "Paton" at character 122 2021-10-18 01:23:16.885 +06 [5964] STATEMENT: INSERT INTO authors (id, author_name, author_slug) VALUES (an3cxZh8ZD3tdtqG4wuwPR, Alan Paton, alan-paton);
Advertisement
Answer
INSERT INTO authors (id, author_name, author_slug) VALUES (an3cxZh8ZD3tdtqG4wuwPR, Alan Paton, alan-paton);
Your string values are not quoted. It would have to be…
INSERT INTO authors (id, author_name, author_slug) VALUES ('an3cxZh8ZD3tdtqG4wuwPR', 'Alan Paton', 'alan-paton');
You could add quotes to your query, but don’t. Your query as written is insecure and vulnerable to a SQL injection attack. Do not insert values into queries with string concatenation.
Instead, use parameters.
const insertSQL = ` INSERT INTO authors (id, author_name, author_slug) VALUES ($1, $2, $3); `; await pool.query( insertSQL, [authorID, authorName, authorSlug] );
Postgres will handle the quoting for you. This is safer, more secure, and faster.
Note that an3cxZh8ZD3tdtqG4wuwPR
is not a valid UUID. A UUID is a 128 bit integer often represented as a 32 character hex string.
Note that you also probably want to use autoincrementing primary keys instead of generating the ID yourself. For a UUID primary key, load the uuid-ossp package and use its UUID function as your default.
create extension "uuid-ossp"; create table authors ( id uuid primary key default uuid_generate_v4(), -- There's no point in arbitrarily limiting the size of your text fields. -- They will only use as much space as they need. author_name text not null unique check (author_name <> ''), author_slug text not null unique check (author_slug <> '') ); insert into authors (author_name, author_slug) values ('Alan Paton', 'alan-paton');