I made a postrgesql database on heroku. Then I tried to access it via a python script. For that I wrote the following code.
import psycopg2
#connect to the db
con = psycopg2.connect(
host = "an_aws_ec2_instance",
database="d57kjtuarj5li8",
user = "mmpywqodjzxlzr",
password = "************************************")
#cursor
cur = con.cursor()
#execute query
cur.execute("CREATE TABLE accounts (user_id serial PRIMARY KEY, username VARCHAR ( 50 ) UNIQUE NOT NULL, password VARCHAR ( 50 ) NOT NULL, email VARCHAR ( 255 ) UNIQUE NOT NULL, created_on TIMESTAMP NOT NULL, last_login TIMESTAMP)")
cur.execute = ("""SELECT * FROM accounts""")
rows = cur.fetchall()
for r in rows:
print (r)
#commit the transcation
con.commit()
#close the cursor
cur.close()
#close the connection
con.close()
But on executing the code, I got the following error.
---> 15 cur.execute = ("""SELECT * FROM accounts""")
16 rows = cur.fetchall()
AttributeError: 'psycopg2.extensions.cursor' object attribute 'execute' is read-only
When you comapare your two SQL lines, there is a major difference.
This calls the method execute on the object cur, with the SQL statement as parameter:
cur.execute("CREATE TABLE accounts (user_id serial PRIMARY KEY, username VARCHAR ( 50 ) UNIQUE NOT NULL, password VARCHAR ( 50 ) NOT NULL, email VARCHAR ( 255 ) UNIQUE NOT NULL, created_on TIMESTAMP NOT NULL, last_login TIMESTAMP)")
This here is something different. Here you are trying to assign a string (the SQL statement) to an attribute (execute), which is read-only on that object.
cur.execute = ("""SELECT * FROM accounts""")
# THIS
if remove the = from the second statement, you're fine.
Related
I've got a PostgreSQL function that inserts into 1 public table from another. Here are the create tables and function codes:
CREATE TABLE IF NOT EXISTS public.a_input
(
in_text character varying COLLATE pg_catalog."default"
)
TABLESPACE pg_default;
CREATE TABLE IF NOT EXISTS public.tot_input
(
in_text character varying COLLATE pg_catalog."default"
)
TABLESPACE pg_default;
insert into public.a_input(
select 'a');
insert into public.a_input(
select 'b');
insert into public.a_input(
select 'c');
CREATE FUNCTION public.inputfunct(
)
RETURNS void
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
AS $BODY$
BEGIN
INSERT INTO public.tot_input (
SELECT
in_text
FROM public.a_input);
END;
$BODY$;
So, the table public.a_input has 3 entries ('a','b','c'). And the public.inputfunct will select those 3 rows and insert them into public.tot_input. I've tested this in PostgreSQL and it works like I expected.
Then, I go over to python and I have this code:
#####################
hostname='localhost'
user='postgres'
password='MyPassword'
dbname='postgres'
################
import psycopg2
#########
try:
con=psycopg2.connect( host=hostname, user=username, password=password, dbname=database )
except NameError:
print('error')
else:
print('connected')
cur=con.cursor()
cur.callproc("public.inputfunct")
con.commit
con.close()
When I run this, the 'connected' message prints, so I know I'm connecting correctly. I don't get an error when this runs. But, When I select from public.tot_input - there are no rows. It's like the function is running, but no rows end up in the tot_input table. Any suggestions?
I am trying to insert values of a dataframe to postgres database. for that i am treating a temporary csv file and load the csv file, load the csv in buffer and using copy_from() i am inserting it into the database.
But Here I am getting an error [WinError 32] The process cannot access the file because it is being used by another process: 'temp.csv'
No other application is open except pycharm. Can some please help!
def copy_from_datafile(conn, df_s, table):
"""
save the given dataframe on disk as a csv file,
load the csv file in buffer and use copy_from() to copy it to the pgsql database table
"""
if table == "symbols_option":
command= '''CREATE TEMPORARY TABLE IF NOT EXISTS _symbol (
instrument_token INTEGER NOT NULL, exchange_token INTEGER, tradingsymbol TEXT NOT NULL, name TEXT,
expiry TIMESTAMP, strike DOUBLE PRECISION, lot_size INTEGER,instrument_type TEXT, segment TEXT NOT NULL, exchange TEXT, PRIMARY KEY (instrument_token,
tradingsymbol));'''
query_main = '''INSERT INTO {table}(instrument_token, exchange_token, tradingsymbol, name, expiry, strike, lot_size,instrument_type, segment, exchange )
SELECT * FROM _symbol
ON CONFLICT (instrument_token, tradingsymbol)
DO NOTHING
'''.format(table=table)
if table == "symbols_future":
command= '''CREATE TEMPORARY TABLE IF NOT EXISTS _symbol (
instrument_token INTEGER NOT NULL,exchange_token INTEGER, tradingsymbol TEXT NOT NULL,name TEXT,
expiry TIMESTAMP,lot_size INTEGER,instrument_type TEXT, segment TEXT NOT NULL, exchange TEXT, PRIMARY KEY (instrument_token,
tradingsymbol));'''
query_main = '''INSERT INTO {table}(instrument_token, exchange_token, tradingsymbol,name, expiry,lot_size,instrument_type, segment, exchange )
SELECT * FROM _symbol
ON CONFLICT (instrument_token, tradingsymbol)
DO NOTHING
'''.format(table=table)
tmp_df = 'temp.csv'
df_s.to_csv(tmp_df, header=False, index=False)
f = open(tmp_df, 'r')
cursor = conn.cursor()
try:
if table == "symbols_option":
# cursor.execute(command)
cursor.execute(command)
cursor.copy_from(f, '_symbol', sep=",", columns=["instrument_token", "exchange_token", "tradingsymbol", "name", "expiry", "strike", "lot_size","instrument_type", "segment", "exchange" ])
cursor.execute(query_main)
print("Data inserted using copy_from_datafile() successfully....")
else:
cursor.execute(command)
cursor.copy_from(f, '_symbol', sep=",", columns=[
"instrument_token", "exchange_token", "tradingsymbol", "name", "expiry", "lot_size",
"instrument_type", "segment", "exchange"])
cursor.execute(query_main)
print("Data inserted using copy_from_datafile() successfully....")
except (Exception, psycopg2.DatabaseError) as err:
os.remove(tmp_df)
print(err)
cursor.close()
else:
os.remove(tmp_df)
The problem now is that I can only enter one record. No errors are recorded. It just takes the first record from one database and puts in the other database. I am trying to create a machine usable database from the user interface database. I will try to transfer around 100 records once it is working. I would appreciate in comments or suggestions. Thank you!
import sqlite3
sql = 'INSERT INTO heavenStream (scene, cascade, enclosure, sensor, streamer, dither) VALUES (?, ?, ?, ?, ?, ?)'
def dropTable(crs,conn):
crs.execute("DROP TABLE IF EXISTS heavenStream")
def createTable(crs,conn):
sql ='''CREATE TABLE heavenStream(
id INTEGER PRIMARY KEY AUTOINCREMENT,
scene TEXT,
cascade TEXT,
enclosure TEXT,
sensor TEXT,
streamer TEXT,
dither TEXT,
timeStream TEXT,
streamTime TEXT
)'''
crs.execute(sql)
print("Table created successfully........")
def insert_one(conn, crs):
crs.execute("SELECT * FROM animalStream")
for row in crs:
scene = row[1]
cascade = row[2]
enclosure = row[3]
sensor = row[4]
streamer = row[5]
dither = row[6]
print(f"{row[1]} {row[2]} {row[3]} {row[4]} {row[5]} {row[6]}")
try:
crs.execute(sql, (scene, cascade, enclosure,
sensor,streamer,dither))
except sqlite3.IntegrityError as err:
print('sqlite error: ', err.args[0]) # column name is
not unique
conn.commit()
def main():
conn = sqlite3.connect("/home/harry/interface/wildlife.db")
crs = conn.cursor()
dropTable(crs,conn)
createTable(crs,conn)
insert_one(conn, crs)
# conn.commit()
conn.close()
print('done')
main()
The user interface database has had records deleted. There is one record with an id of 64 and the rest are in the 90's.
The cursor (crs) changes here
crs.execute(sql, (scene, cascade, enclosure,sensor,streamer,dither))
after the first insert. Therefore, there are "no more rows to fetch" in the orginal crs.
One solution would be to instantiate another cursor for the insert. Another solution would be to fetchall() the rows into a variable and iterate over that variable as with:
rows = crs.execute("SELECT * FROM animalStream").fetchall()
for row in rows:
I wrote the following script for uploading a csv file to postgresql databse.
import psycopg2
import keys
con = psycopg2.connect(
host = keys.keys['host'],
database = keys.keys['database'],
user = keys.keys['user'],
password = keys.keys['password'])
#cursor
cur = con.cursor()
#execute query
#Already created ___#cur.execute("CREATE TABLE accounts (user_id serial PRIMARY KEY, username VARCHAR ( 50 ) UNIQUE NOT NULL, password VARCHAR ( 50 ) NOT NULL, email VARCHAR ( 255 ) UNIQUE NOT NULL, created_on TIMESTAMP NOT NULL, last_login TIMESTAMP)")
cur.execute("""\COPY "MyData" FROM 'C:\FILES\TestData.csv' DELIMITER ',' CSV HEADER;""")
#commit the transcation
con.commit()
#close the cursor
cur.close()
#close the connection
con.close()
But it returned the following error:-
SyntaxError: syntax error at or near "\"
LINE 1: \COPY "MyData" FROM 'C:\FILES\TestData.csv' DELIMITER ',' C...
I'm not a root user, so I could not directly use the COPY command.
Well.
You can use psycopg2's copy_from -> https://www.psycopg.org/docs/cursor.html#cursor.copy_from
So your code would look something like:
import psycopg2
import keys
con = psycopg2.connect(
host = keys.keys['host'],
database = keys.keys['database'],
user = keys.keys['user'],
password = keys.keys['password'])
#cursor
cur = con.cursor()
#execute query
#Already created ___#cur.execute("CREATE TABLE accounts (user_id serial PRIMARY KEY, username VARCHAR ( 50 ) UNIQUE NOT NULL, password VARCHAR ( 50 ) NOT NULL, email VARCHAR ( 255 ) UNIQUE NOT NULL, created_on TIMESTAMP NOT NULL, last_login TIMESTAMP)")
with open('C:\\Files\\TestData.csv', 'r') as acc:
next(acc) # This will skip the header
cur.copy_from(acc, 'accounts', sep=',')
#commit the transcation
con.commit()
#close the cursor
cur.close()
#close the connection
con.close()
Hope this answers your question.
I created one-to-many relationship table and according to the sqlite3 documentation I can't insert value into the child table if the referenced table column value in the parent table does not exist.
import sqlite3
class Database:
def __init__(self, database_name):
self.database_name = database_name
def create_table(self, table_name, *columns):
columns = ", ".join(columns)
conn = sqlite3.connect(self.database_name)
cursor = conn.cursor()
_SQL = f"CREATE TABLE IF NOT EXISTS {table_name}({columns})"
cursor.execute(_SQL)
conn.commit()
cursor.close()
conn.close()
def insert_values(self, table_name, values, *columns):
dynamic_values = ('?, ' * len(columns))[0:-2]
columns = ", ".join(columns)
conn = sqlite3.connect(self.database_name)
cursor = conn.cursor()
_SQL = f"INSERT INTO {table_name}({columns}) VALUES ({dynamic_values})"
cursor.execute(_SQL, values)
conn.commit()
cursor.close()
conn.close()
def view_values(self, table_name, *columns):
columns = ", ".join(columns)
conn = sqlite3.connect(self.database_name)
cursor = conn.cursor()
_SQL = f"SELECT {columns} FROM {table_name}"
cursor.execute(_SQL)
the_data = cursor.fetchall()
cursor.close()
conn.close()
return the_data
data = Database("games.db")
#
# data.create_table("supplier_groups", "group_id integer PRIMARY KEY", "group_name text NOT NULL")
#
data.insert_values("supplier_groups", ("Domestic", ), "group_name")
# data.create_table("suppliers ", "supplier_id INTEGER PRIMARY KEY",
# "supplier_name TEXT NOT NULL",
# "group_id INTEGER NOT NULL, "
# "FOREIGN KEY (group_id) REFERENCES supplier_groups (group_id)")
data.insert_values("suppliers", ('ABC Inc.', 9), "supplier_name", "group_id")
as you see on this line: data.insert_values("supplier_groups", ("Domestic", ), "group_name") - I'm inserting a value into supplier_groups table
and then right here: data.insert_values("suppliers", ('ABC Inc.', 9), "supplier_name", "group_id") - I'm inserting value into suppliers table with the group_id that does not exist in the group_suppliers table. Python executes it successfully and adds value to the database, however when attemping to execute this command in SQLITE browser I get this error:
Execution finished with errors. Result: FOREIGN KEY constraint failed which is what python should also have done instead of adding it into the database.
So, could anyone explain me what's going on here? Do I understand something in the wrong way? Help would be appreciated
From Section 2. Enabling Foreign Key Support in the sqlite doc:
Assuming the library is compiled with foreign key constraints enabled, it must still be enabled by the application at runtime, using the PRAGMA foreign_keys command. For example:
sqlite> PRAGMA foreign_keys = ON;