psycopg2.OperationalError: FATAL: database does not exist - python

I'm trying to populate a couple databases with psycopg2 within a server I am not the root user of (don't know if it's relevant or not). My code looks like
import json
from psycopg2 import connect
cors = connect(user='jungal01', dbname='course')
req = connect(user="jungal01", dbname='requirement')
core = cors.cursor()
reqs = req.cursor()
with open('gened.json') as gens:
geneds = json.load(gens)
for i in range(len(geneds)):
core.execute('''insert into course (number, description, title)
values({0}, {1}, {2});''' .format(geneds[i]["number"], geneds[i]['description'], geneds[i]['title'] ))
reqs.execute('''insert into requirement (fulfills)
values({0});''' .format(geneds[i]['fulfills'] ))
db.commit()
when I execute the code, I get the above pycopg2 error. I know that these particular databases exist, but I just can't figure out why it won't connect to my databases. (side quest, I am also unsure about that commit statement. Should it be in the for loop, or outside of it? It suppose to be database specific?)

First, you have db is not a defined variable, so you code shouldn't run completely anyway.
\list on this server is a bunch of databases full of usernames, of which my username is one
Then the following is how you should connect. To a database, not a table, and the regular pattern is to put the database name, and then the user/pass.
A "schema" is a loose term in relational database. Both tables and databases have schemas, but you seem to be expecting to connect to a table, not a database.
So, try this code with an attempt at fixing your indentation and SQL injection problem -- See this documentation
Note that you first must have created the two tables in the database you are connecting to.
import json
from psycopg2 import connect
username = 'jungal01'
conn = connect(dbname=username, user=username)
cur = conn.cursor()
with open('gened.json') as gens:
geneds = json.load(gens)
for g in geneds:
cur.execute('''insert into course (number, description, title)
values(%(number)s, %(description)s, %(title)s);''', g)
cur.execute('''insert into requirement (fulfills)
values(%(fulfills)s);''', g)
conn.commit()

Allen, you said: "in postgres, tables are databases." That's wrong. Your error message results from this misunderstanding. You want to connect to a database, and insert into a table that exists in that database. You're trying to insert into a database -- a nonsensical operation.

Make sure you are giving the catalog name as database name and not the schema's under catalog.
Catalog is confusing and quite unnecessary. More details below: What's the difference between a catalog and a schema in a relational database?

Related

How to set postgres and psycopg2 so that it always searches the schema without having to explicitly mention it?

I have a postgres DB where I have run this command to avoid having to mention schema explicitly:
ALTER DATABASE ibkr_trader SET search_path TO public;
However, when I connect using psycopg2 in python, I still have to type this to access my tables:
select count(*) from "public"."MY_TABLE"
I even tried setting options in psycopg2.connect but it didn't work:
return psycopg2.connect(
dbname=self.dbname,
user=self.user,
password=self.password,
port=self.port,
host=self.host,
options="-c search_path=public"
)
What is the most elegant way to set this network up so that I don't have to type "public":"MY_TABLE" for each query? I do not have any other schemas in my DB and I don't wanna have to mention it explicitly.
Your ALTER DATABASE and your options="-c search_path=public" both work for me. But then again public is usually already in your search path, so neither of them should be needed at all unless you went out of your way to break something.
I suspect you are misinterpreting something. If you try select count(*) from MY_TABLE, that won't work. Not because you are missing the "public", but because you are missing the double quotes around "MY_TABLE" and therefore are searching for the table by a down-cased name of "my_table".
The default search path should look like `"$user", public'", meaning that tables / views in the public schema may be referenced without specifying the schema name, and the server will first search through the schema that matches the role name, and then the public schema. Evidently this has been altered on your server.
It is possible to set the search_path for each user. The alter user command would look like.
alter user username set search_path = 'public'

AppScreener says that my SQL code has some SQL Injection vulnerabilities

I am developing a project where I will have a backup of some forums and information coming from Lotus Notes. I am using Flask to run the backend. After check my code with the code scanner AppScreener, it says that my SQL code has some SQL Injection vulnerabilities but I can't undestand why.
This is the AppScreener result:
for usuario in data:
print("Usuario", usuario)
status = usuario['estatus_usuario']
mail = usuario['email_usuario']
cursor = conn.cursor()
cursor.execute( "UPDATE administrador_usuarios SET estatus_usuario=%s
WHERE email=%s",(status,mail)) # ---> this is the line where according to AppScreener is the vulnerability present
conn.commit()
conn.close()
return json.dumps({"response":"ok"})
Could you tell me what I can do?
It really depends on the DBAPI you're using for sql (pyodbc, pymysql, sqlite, etc). In most of these, I think the %s notation got depreciated a while ago. Best to use ? as people have commented (referenced links).

sql INSERT in python (postgres, cursor, execute)

I had no problem with SELECTing data in python from postgres database using cursor/execute. Just changed the sql to INSERT a row but nothing is inserted to DB. Can anyone let me know what should be modified? A little confused because everything is the same except for the sql statement.
<!-- language: python -->
#app.route("/addcontact")
def addcontact():
# this connection/cursor setting showed no problem so far
conn = pg.connect(conn_str)
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
sql = f"INSERT INTO jna (sid, phone, email) VALUES ('123','123','123')"
cur.execute(sql)
return redirect("/contacts")
first look at your table setup and make sure your variables are named right in the right order, format and all that, if your not logging into the specific database on the sql server it won't know where the table is, you might need to send something like 'USE databasename' before you do your insert statement so your computer is in the right place in the server.
I might not be up to date with the language but is that 'f' supposed to be right before the quotes? if thats in ur code that'd probably throw an error unless it has a use im not aware of or its not relevant to the problem.
You have to commit your transaction by adding the line below after execute(sql)
conn.commit()
Ref: Using INSERT with a PostgreSQL Database using Python

SQLAlchemy - get date that table was created

I'm connecting to an Oracle database from sqlalchemy and I want to know when the tables in the database were created. I can access this information through the sql developer application so I know that it is stored somewhere, but I don't know if its possible to get this information from sqlalchemy.
Also if its not possible, how should I be getting it?
SqlAlchemy doesn't provide anything to help you get that information. You have to query the database yourself.
something like:
with engine.begin() as c:
result = c.execute("""
SELECT created
FROM dba_objects
WHERE object_name = <<your table name>>
AND object_type = 'TABLE'
""")

Correct Postgresql syntax

I'm a postgres newbie and am having some issues querying a text field in postgresql using Python. What is the correct syntax that will allow me to search the content of column "body" from table "jivemessage" out of database "postgres"?
try:
conn = psycopg2.connect("dbname='postgres' user='postgres' host='localhost' password='<password>'")
except:
print "cannot connect"
i = 'test'
cur = conn.cursor()
cur.execute('SELECT * from jivemessage WHERE body LIKE "%'+i+'%"')
Keep getting the following error:
ProgrammingError: column "%test%" does not exist
Thanks for any help.
You are not quoting the query properly. Don't use string concatenation here, use SQL parameters instead:
cur.execute('SELECT * from jivemessage WHERE body LIKE %s', ("%{}%".format(i),))
Here, the %s placeholder signals to the database driver that the first value of the second argument should be placed there when querying.
This leaves the interpolation up to the database driver, giving the database the opportunity to optimize for the query once, even if you were to reuse the same query.
It also prevents SQL injection attacks better than you could yourself, and most of all, guarantees that the correct quoting rules are followed.

Categories