why the select query through python throwing syntax error? - python

I am trying to connect to a Postgres DB and execute a simple select query. But I am getting errors. Below is the sample program
import psycopg2 as ps
param_dic = ps.connect(
host="localhost",
database="Test_DB",
user="username",
password="password"
)
cur = param_dic.cursor()
cur.execute("select * from <schema_name>.'employee_tbl'") # I am
rows = cur.fetchall()
for r in rows:
print(r)
I get below error:
psycopg2.errors.SyntaxError: syntax error at or near "'tbl_name'"
LINE 1: select * from <schema_name>.'tbl_name'
If I use
cur.execute("select * from <schema_name>.'Employee_TBL'")
Still, I get the same error.
Note: when I check my pgAdmin, I see below as the table name
<schema_name>.Employee_TBL
So, what is the right way to execute SQL queries on a Postgres table?

replace <schema_name>.'Employee_TBL'" with true value :
dbo.Employee_TBL or another schema name in your database

Maybe it's just a typo, use double quotes for the table if you need to.
Single quotes indicate a string literal.
import psycopg2
conn = psycopg2.connect(...)
cur = conn.cursor()
cur.execute('SELECT * FROM public.servers')
print(len(cur.fetchall()))
cur.execute('SELECT * FROM PUBLIC."servers"')
print(len(cur.fetchall()))
Out:
6
6

Try removing quotes around ‘emloyee_tbl’

The overriding issue is that you created a table name with quoted mixed case. This means that from then on you need to quote the name to be able to use it:
create table "Mixed_Case" (id int, fld_1 varchar);
select * from mixed_case;
ERROR: relation "mixed_case" does not exist
LINE 1: select * from mixed_case;
select * from "Mixed_Case";
id | fld_1
----+-------
(0 rows)
--NOTE the double quotes.
For more information see 4.1.1. Identifiers and Key Words
For the psycopg2 case:
import psycopg2
con = psycopg2.connect("dbname='test' host='localhost' user='aklaver'")
cur = con.cursor()
# Single quoted
cur.execute("select * from public.'Mixed_Case'")
SyntaxError: syntax error at or near "'Mixed_Case'"
LINE 1: select * from public.'Mixed_Case'
# Identifiers need double quotes
# Changing to double quotes
cur.execute('select * from public."Mixed_Case"')
# No error.
# You can also use Postgres functions
cur.execute("select * from quote_ident('public.Mixed_Case')")
For more on Postgres functions and methods see string functions
Also in psycopg2 there is the sql module that allows you to work with identifiers:
from psycopg2 import sql
sql_str = sql.SQL("select * from public.{}").format(sql.Identifier('Mixed_Case'))
print(sql_str.as_string(con))
select * from public."Mixed_Case"
cur.execute(sql_str)

Related

How to specify a dot separated table as a parameter into the sql query

For purposes of this question, let's say there is a table schema foo.bar.baz
And we have created a cursor object using following boilerplate
import snowflake.connector
ctx = snowflake.connector.connect(...)
cur = ctx.cursor()
With that cursor object, we can put the whole dot deliminated schema into a query like so:
cur.execute('''
select * from foo.bar.baz
'''
)
and have no issues, but we wouldn't be able to do:
cur.execute('''
select * from %(tbl)s
''', {'tbl': 'foo.bar.baz'}
)
Doing that throws this type of error: ProgrammingError: 001011 (42601): SQL compilation error: invalid URL prefix found in: foo.bar.baz
I'm guessing this is because the dots are sql identifiers and not strings, but I don't see any workaround in the snowflake documentation. Does anyone know how this could be done without having to change the connection object.
Using TABLE:
In a FROM clause, the syntax TABLE( { string_literal | session_variable | bind_variable } ) can be used
select * from TABLE(%(tbl)s)

Python2.7 - SQLite3 library outputs error message "sqlite3.OperationalError: near "?": syntax error"

Code is follow. How to get replaced ? by value of variables [table, url]?
Expected SQL command is select * from OTHER_URL where url="http://a.com/a.jpg"
This SQL command occurs no error on the sqlite3 command line interface.
import sqlite3
from contextlib import closing
dbname = "ng.db"
with closing(sqlite3.connect(dbname)) as conn:
c = conn.cursor()
c.execute("CREATE TABLE IF NOT EXISTS OTHER_URL (url TEXT)")
conn.commit()
table = "OTHER_URL"
url = "http://a.com/a.jpg"
with closing(sqlite3.connect(dbname)) as conn:
c = conn.cursor()
c.execute('select * from ? where url="?"', [table, url])
print c.fetchone()
There are two errors here. Firstly, you can't use parameter substitution for table names (or column names), only for values. You need to use string interpolation for anything else.
Secondly, you don't need quotes around the value parameter; the substitution will take care of that.
So:
c.execute('select * from {} where url=?'.format(table), [url])

Getting data from schema in psycopg2

I try to connect to Postgres database inside my Python app.
I use psycopg2 library.
If I execute select statement like this:
cursor.execute("""select schema_name from information_schema.schemata;""")
rows = cursor.fetchall()
print(rows)
and I get :
[('DB_FZ',), ('DB_FZ_TEMP',), ...]
but if I execute statement
cursor.execute("""select * from DB_FZ.d_results;""")
rows = cursor.fetchall()
print(rows)
I get error
psycopg2.ProgrammingError: schema "db_fz" does not exist
LINE 1: select * from DB_FZ.d_results;
What could be wrong?
The schema name is in uppercase, you should put it in double quotes:
cursor.execute("""select * from "DB_FZ".d_results;""")
See also Are PostgreSQL column names case-sensitive?

Unable to execute a query in Python/Django which contains non-latin characters

I try to execute a query in Python/Django, but eventually I end up with ProgrammingError. My script looks like this:
#--coding: utf-8
...
import pyodbc
...
def testquery(request):
cnx = pyodbc.connect("DRIVER=FreeTDS;SERVER=192.168.0.1;PORT=1433;DATABASE=mydatabase;UID=sa;PWD=password;TDS_Version=7.0;ClientCharset=UTF8;")
cursor = cnx.cursor()
cursor.execute("SELECT * FROM sys_Атрибут")
...
As you can see, the name of a table contains non-latin characters. If I instead query another table, whose name is in Latin, then it's ok.
I also tried this:
cursor.execute("SELECT * FROM ?",tablename)
And this:
cursor.execute("SELECT * FROM %s" % tablename)
But it has no effect.
"FreeTDS handles Unicode for you" https://stackoverflow.com/a/964825/3033586
cursor.execute(u'SELECT * FROM sys_Атрибут'.encode('utf-8'))

psycopg2, SELECT, and schemas

I'm trying to do a simple select statement on a table that's part of the "dam_vector" schema. The error I get is:
psycopg2.ProgrammingError: relation
"dam_vector.parcels_full" does not
exist LINE 1: SELECT * FROM
"dam_vector.parcels_full"
I can't figure this out and know I'm missing something obvious. Any help you can provide would be great.
Here's the code I'm using. db is a connection string that successfully connects to the database.
cur = db.cursor()
query = 'SELECT * FROM "dam_vector.parcels_full"'
cur.execute(query)
results = cur.fetchall()
and when that failed and after I did some research on Google I tried this. Same error.
cur.execute("SET search_path TO dam_vector,public")
db.commit()
cur = db.cursor()
query = 'SELECT * FROM "parcels_full"'
cur.execute(query)
results = cur.fetchall()
Double quotes makes whatever is in them an identifier, so query
SELECT * FROM "dam_vector.parcels_full";
hits table dam_vector.parcels_full (period interpreted as part of table name) from schama public (or anything in search path).
As Adam said, you don't need quotes with names without some special characters.
Try:
SELECT * FROM dam_vector.parcels_full;
If you really want to use a double quotes, go for:
SELECT * FROM "dam_vector"."parcels_full";
You shouldn't need the quotes around dam_vector.parcels_full.
Does the output of the following show that a parcels_full table is indeed present?
cur.execute("""SELECT tablename
FROM pg_tables
WHERE tablename NOT LIKE ALL (ARRAY['pg_%','sql_%']);""")
cur.fetchall()

Categories