Python psycopg2 - using .format() with a dbname inside a string - postgresql

I'm using psycopg2 to query a database that starts with a number + ".district", so my code goes like:
number = 2345
cur = conn.cursor()
myquery = """ SELECT *
FROM {0}.districts
;""".format(number)
cur.execute("""{0};""".format(query))
data = cur.fetchall()
conn.close()
And i keep receiving the following psycopg2 error..
psycopg2.ProgrammingError: syntax error at or near "2345."
LINE 1: SELECT * FROM 2345.districts...
Thought it was the type of data the problem, maybe int(number) or str(number)..but no, same error appears.
¿ What am i doing wrong ?

The way you are trying to use to pass parameters is not supported. Please read the docs.

Related

how to link python pandas dataframe to mysqlconnector '%s' value

I am trying to pipe a webscraped pandas dataframe into a MySql table with mysql.connector but I can't seem to link df values to the %s variable. The connection is good (I can add individual rows) but it just returns errors when I replace the value witht he %s.
cnx = mysql.connector.connect(host = 'ip', user = 'user', passwd = 'pass', database = 'db')
cursor = cnx.cursor()
insert_df = ("""INSERT INTO table"
"(page_1, date_1, record_1, task_1)"
"VALUES ('%s','%s','%s','%s')""")
cursor.executemany(insert_df, df)
cnx.commit()
cnx.close()
This returns "ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()."
If I add any additional oiperations it returns "ProgrammingError: Parameters for query must be an Iterable."
I am very new to this so any help is appreciated
Work around for me was to redo my whole process. I ran sqlalchemy, all the documentation makes this very easy. message if you want the code I used.

Formatting SQL query

I am trying to make a query for my PostgreSQL database.
I think the format of my query is wrong and I can't seem to get it to work, I have posted my code below:
query = cur.execute('SELECT "KINASE_NAME" FROM public."Phosphosite_table"
WHERE "GENE_NAME" LIKE %(genename)s AND "RESIDUE" LIKE %(location)s')
The aim is to take the kinase name is the gene name and location match.
my error message appears as the following:
ProgrammingError Traceback (most recent call last)
<ipython-input-33-9eae43b913d6> in <module>()
35 cur = connection.cursor()
36
---> 37 query = cur.execute('SELECT "KINASE_NAME" FROM public."Phosphosite_table" WHERE "GENE_NAME" LIKE%(genename)s AND "RESIDUE" LIKE %(location)s')
Thanks!
Connor
Don't use string operations to build SQL queries. Use the proper %s syntax.
genname = "foo"
location = "bar"
cur.execute("SELECT ... LIKE %s and ... LIKE %s", (genname, location))
No quotes around the values must be used. The quoting will be done by the DB API library.

How to make psycopg2 emit no quotes?

I want to create a table from Pytnon:
import psycopg2 as pg
from psycopg2 import sql
conn = pg.connect("dbname=test user=test")
table_name = "testDB"
column_name = "mykey"
column_type = "bigint"
cu = conn.cursor()
cu.execute(sql.SQL("CREATE TABLE {t} ({c} {y})").format(
t=sql.Identifier(table_name),
c=sql.Identifier(column_name),
y=sql.Literal(column_type)))
Alas, this emits CREATE TABLE "testDB" ("mykey" 'bigint') which fails with a
psycopg2.ProgrammingError: syntax error at or near "'bigint'"
Of course, I can do something like
cu.execute(sql.SQL("CREATE TABLE {t} ({c} %s)" % (column_name)).format(
t=sql.Identifier(table_name),
c=sql.Identifier(column_name)))
but I suspect there is a more elegant (and secure!) solution.
PS. See also How to make psycopg2 emit nested quotes?
There is an example in the documentation how to build a query text with a placeholder. Use psycopg2.extensions.AsIs(object) for column_type:
query = sql.SQL("CREATE TABLE {t} ({c} %s)").format(
t=sql.Identifier(table_name),
c=sql.Identifier(column_name)).as_string(cu)
cu.execute(query, [AsIs(column_type)])

PostgreSQL {call Update Set ...} getting "syntax error at or near SET"

I'm changing queries from an Oracle Database to PostgreSQL, and in this query I am getting this error:
ERROR: syntax error at or near "SET"
the query is:
{call UPDATE alarm_instance SET last_update_time=default, wait_expire_time=null, core_number=nextval(SEQ_ALRM_NUMBR)
where wait_time <= current_date RETURNING alarm_instance_id bulk collect INTO ?}
I am using JDBC to connect to the database and here is the call code
try (CallableStatement cs = super.prepareCall_(query)) {
cs.registerOutParameter(1, Types.ARRAY);
cs.execute();
...
I have taken a long look at Postgres documentation and cannot find what is wrong and didn't find any answer to this specific situation
An UPDATE statement can't be executed with a CallableStatement. A CallableStatement is essentially only intended to call stored procedures. In case of Oracle that includes anonymous PL/SQL blocks.
And bulk collect is invalid in Postgres to begin with.
It seems you want something like this:
String sql =
"UPDATE alarm_instance " +
" SET last_update_time=default, " +
" wait_expire_time=null, "
" core_number=nextval('SEQ_ALRM_NUMBR') " +
" where wait_time <= current_date RETURNING alarm_instance_id";
Statement stmt = connection.createStatement();
stmt.execute(sql);
int rowsUpdated = stmt.getUpdateCount();
ResultSet rs = stmt.getResultSet();
while (rs.next() {
// do something with the returned IDs
}

How to make psycopg2 emit nested quotes?

As per "relation does not exist" in pg_table_size, I need to emit nested single and double quotes:
import psycopg2 as pg
from psycopg2 import sql
conn = pg.connect("dbname=test user=test")
table_name = "testDB"
cu = conn.cursor()
cu.execute(sql.SQL("SELECT pg_table_size(%s)"), (table_name,))
emits SELECT pg_table_size('testDB') which raises
psycopg2.ProgrammingError: relation "testdb" does not exist
while
cu.execute(sql.SQL("SELECT pg_table_size({t})").format(t=sql.Identifier(table_name)))
emits SELECT pg_table_size("testDB") which raises
psycopg2.ProgrammingError: column "testDB" does not exist
Obviously,
cu.execute(sql.SQL("SELECT pg_table_size(%s)"),('"testDB"',))
works fine, but I want to find the "official" way to emit SELECT pg_table_size('"testDB"').
Experimentally, the following works:
cu.execute(sql.SQL("SELECT pg_table_size(%s)"),
(sql.Identifier(table_name).as_string(conn), ))
is this TRT?
You can use the Postgres function quote_ident(string text):
cu.execute("SELECT pg_table_size(quote_ident(%s))", (table_name, ))
I think your last example is a good alternative for the above solution.