In pgAdmin (PostgresAdmin) I execute the following query:
SELECT category.name, subcategory.name
FROM category
JOIN category_subcategory ON category_subcategory.category_id = category.category_id
JOIN subcategory ON category_subcategory.subcategory_id = subcategory.subcategory_id
ORDER BY category.name, subcategory.name;
The table resulted after executing the query resembles everything correct, my aim was to establish a many-to-many relationship between category, subcategory and category_subcategory tables.
QUESTION
How can I resemble the same logic using TypeORM, so that the query is executed as soon as I start the backend server?
The tech stack that I am using is Nest.js, TypeORM, PostgreSQL
I tried entering the query in the code, however I get the following result
Using the Keyword Query from the Robot Framework DatabaseLibrary JayDeBeApi in conjunction with DB2 like this: ${results}= Query CREATE TABLE SCHEMANAME.TEST_TEMP (id BIGINT, name VARCHAR(25)) is being executed (table exists afterwards).
But nevertheless RobotFramework throws a FAIL and ${results} contains the Message DatabaseError: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-601, SQLSTATE=42710, SQLERRMC=SCHEMANAME.TEST_TEMP;TABLE, DRIVER=4.14.122 and often even a very simple Message Error after running the same statement.
Running the query above (copy/paste) directly within a database SQL window doesn't return any errors.
How is it possible, in RobotFramework the query is executed successfully but nevertheless an error is thrown?
The error SQLCODE=-601 means that you are trying to create an object that already exists. So when you say that the table exists afterwards, it means that it existed before you ran the statement. I don't know the framework you are using, but the explanation by #pavelsaman in comment seems to be a very likely cause.
I loaded some sample data into Db2 Warehouse on Cloud but I'm not able to execute even basic SQL queries since I'm always getting "QL0206N: SQL0206N "[column_name]" is not valid in the context where it is used. SQLSTATE=42703".
for example: select log_id from m1
I tried multiple variants like
select m1.log_id from m1
select m1.log_id from dash6792.m1
select message.log_id from dash6792.m1 as message => still getting the same error.
I also tried different columns and tried to put them into different places of the query (e.g. in "where" or "on" clauses) => the same result.
Surprisingly, I can query tables from sample schemas (e.g. "GOSALES") normally => so the problem occurs only for my schema (but for all tables).
I am writing a simple python prog to connect and display results from Postgres table this is on AWS RDS. I have table mytest in public schema.
connection = psycopg2.connect(dbname='some_test',
user='user1',
host='localhost',
password='userpwd',
port=postgres_port)
cursor = connection.cursor()
cursor.execute("SET SEARCH_PATH TO public;")
cursor.execute("SELECT * FROM mytest;")
But this throws an error
psycopg2.ProgrammingError: relation "mytest" does not exist
LINE 1: SELECT * FROM mytest;
Connection is successful and I can query other basetables like
SELECT table_name FROM information_schema.tables
It is just that I cannot change to any other schema. I googled and tried all kinds of SET SERACH_PATH and commit it and recreate cursor etc. but no use. I cannot query any other schema.
ALTER USER username SET search_path = schema1,schema2;
After setting this the query works fine!
I am building an Ecto query like this:
from item in query,
where: like(item.description, ^"%#{text}%")
I'm concerned that this allows SQL injection in text. Before trying to fix that, I want to see how the query is actually sent to the database.
If I inspect the query or look at what is logged, I see some SQL, but it's not valid.
For instance, inspecting the query shows me this:
{"SELECT i0.\"id\", i0.\"store_id\", i0.\"title\", i0.\"description\"
FROM \"items\" AS i0 WHERE (i0.\"description\" LIKE $1)",
["%foo%"]}
When I pass this query to Repo.all, it logs this:
SELECT i0."id", i0."store_id", i0."title", i0."description"
FROM "items" AS i0 WHERE (i0."description" LIKE $1) ["%foo%"]
But if I copy and paste that into psql, PostgreSQL gives me an error:
ERROR: 42P02: there is no parameter $1
It seems as though Ecto may actually be doing a parameterized query, like this:
PREPARE bydesc(text) AS SELECT i0."id",
i0."store_id", i0."title", i0."description"
FROM "items" AS i0 WHERE (i0."description" LIKE $1);
EXECUTE bydesc('foo');
If so, I think that would prevent SQL injection. But I'm just guessing that this is what Ecto does.
How can I see the actual SQL that Ecto is executing?
Ecto uses only prepared statements. When using ecto query syntax, introducing SQL injection is not possible. The query syntax verifies at compile-time that no SQL injection is possible.
Showing exactly the queries executed might be difficult because of couple reasons:
Postgrex (and hence Ecto) uses the postgresql binary protocol (instead of the most common, but less efficient, text protocol), so the PREPARE query never actually exists as a string.
For most cases all you would see would be one initial PREPARE 64237612638712636123(...) AS ... and later a lot of EXECUTE 64237612638712636123(...) which isn't that helpful. Trying to relate one to another would be horrible.
From my experience most software of that kind, use prepare statements and log them instead of raw queries, since it's much more helpful in understanding the behaviour of the system.
Yes, that is the exact SQL that is being executed by Ecto (it uses prepared queries through the db_connection package internally) and no SQL injection is possible in that code. This can be verified by turning on logging of all executed SQL queries by changing log_statement to all in postgresql.conf:
...
log_statement = 'all'
...
and then restarting PostgreSQL and running a query. For the following queries:
Repo.get(Post, 1)
Repo.get(Post, 2)
this is logged:
LOG: execute ecto_818: SELECT p0."id", p0."title", p0."user_id", p0."inserted_at", p0."updated_at" FROM "posts" AS p0 WHERE (p0."id" = $1)
DETAIL: parameters: $1 = '1'
LOG: execute ecto_818: SELECT p0."id", p0."title", p0."user_id", p0."inserted_at", p0."updated_at" FROM "posts" AS p0 WHERE (p0."id" = $1)
DETAIL: parameters: $1 = '2'