I am trying to create an ".app" from Automator to run a simple python script. When I execute the script in Automator an error occurs saying more or less "Check your action properties and execute again".
And in the history it says "Traceback (most recent call last:)". The point is that this script is running well with a Terminal session.
It seems to be at least an error with my loop "While" for renaming databases (see below) since I can execute the script up to this stage. Is it something wrong with managing sqlite databases? But I cannot understand since there is no problem with the Terminal. Is anything missing?
My python script:
#!/usr/bin/python
import sqlite3
import os.path
file_name = "newDB.data"
choice = ""
if os.path.isfile(file_name):
choice = raw_input("Erase DB? press [y] or [n]:\n")
if choice == "y":
print "erase"
while True:
try:
os.remove(file_name)
break
except OSError as e: # name the Exception `e`
print "Failed with:", e.strerror # look what it says
print "Error code:", e.code
if choice == "n":
print "Bye!"
exit()
# start sqlite connection
conn = sqlite3.connect("newDB.data")
c = conn.cursor()
# attach
c.execute("ATTACH database 'store1.data' AS db1")
c.execute("ATTACH database 'store2.data' AS db2")
# rename tables
while True:
try:
c.execute("ALTER TABLE db1.ZPATIENT RENAME TO table1")
print "table 1 renamed"
break
except:
c.execute("ALTER TABLE db1.table1 RENAME TO ZPATIENT")
print "except 1"
while True:
try:
c.execute("ALTER TABLE db2.ZPATIENT RENAME TO table2")
print "table 2 renamed"
break
except:
c.execute("ALTER TABLE db2.table2 RENAME TO ZPATIENT")
print "except 2"
# some information commands (START):
c.execute("SELECT * from table1")
print(c.fetchall())
c.execute("SELECT * from table2")
print(c.fetchall())
# some information commands (END)
#c.execute("create table ZPATIENT as select * from table1 union select * from table2") ---> first union action but some entries duplicated (one column changed?)
# remove some duplicated entries...
c.execute("create table ZPATIENT as select * from (select * from table1 union select * from table2) final group by ZDATECREATED")
c.execute("CREATE TABLE Z_PRIMARYKEY (Z_ENT int, Z_NAME text, Z_SUPER int, Z_MAX int)")
c.execute("CREATE TABLE Z_METADATA (Z_VERSION int, Z_UUID text, Z_PLIST BLOB)")
c.execute("SELECT count(*) FROM ZPATIENT")
result=c.fetchone()
number_of_rows=result[0]
print number_of_rows
start = 0
end = number_of_rows + 1
c.execute('SELECT * FROM ZPATIENT')
newresult=c.fetchall()
for row in newresult:
start += 1
end -= 1
print start
print end
# some information commands (START):
list_of_tuple = list(row)
list_of_tuple[0] = start
list_of_tuple[2] = end
row = tuple(list_of_tuple)
print row
# some information commands (END)
c.execute("UPDATE ZPATIENT SET Z_PK = ? WHERE rowid = ?", (start, start))
c.execute("UPDATE ZPATIENT SET Z_OPT = ? WHERE rowid = ?", (end, start))
c.execute("INSERT INTO Z_PRIMARYKEY (Z_ENT, Z_NAME, Z_SUPER, Z_MAX) VALUES (0, 'Patient', 0, ?)", (start,))
# close
conn.commit()
conn.close()
To be working I have two sqlite databases named store1.data and store2.data in the same folder...
If anyone has a solution... I don't know if maybe there is an easier way to execute this in one click?
One simple solution could be to avoid using automator and just make a bash script to call the python script. You can execute the bash script by double-clicking on it if that's what you wanted.
#! /bin/bash
python scriptname.py
is all you would need.
Related
This is my trigger
cursor.execute(
'''CREATE TRIGGER IF NOT EXISTS Car_Park_row_
BEFORE INSERT ON Car_Park
WHEN (SELECT COUNT(*) FROM Car_PARK) >= 10
BEGIN
SELECT RAISE (ABORT, 'FULL');
END;
and this is my function
def C(x):
print('Error')
# Create Database
connector = sqlite3.connect('cparks.db')
connector.create_function("sql", -1, C)
cursor = connector.cursor()
I've limited my rows on my database to 10 with the trigger. What I need now is a message box or something along the lines of to appear to let the GUI user know that the table is full.
Executing the RAISE() function in a query raises a sqlite3.IntegrityError exception in the Python code which you can handle like any other exception.
Example script:
import sqlite3
db = sqlite3.connect(':memory:')
db.executescript('''
CREATE TABLE car_park (car);
CREATE TRIGGER car_park_row
BEFORE INSERT ON car_park
WHEN (SELECT count(*) FROM car_park) >= 10
BEGIN
SELECT RAISE (ABORT, 'full');
END;
''')
for i in range(15):
car = f'car{i}'
try:
res = db.execute('insert into car_park values (?)', (car,))
except sqlite3.IntegrityError as e:
print(f'Could not insert {car}: {e}')
for row in db.execute('SELECT * FROM car_park'):
print(row)
Output:
Could not insert car10: full
Could not insert car11: full
Could not insert car12: full
Could not insert car13: full
Could not insert car14: full
('car0',)
('car1',)
('car2',)
('car3',)
('car4',)
('car5',)
('car6',)
('car7',)
('car8',)
('car9',)
(It may be advisable to break out of the loop if an error occurs, it is not done here just for demonstration purposes.)
Instead of printing an error message, you can call any Python function in the exception handler. You do not need to add a user-defined function to the database to do this:
def handle_insert_car_error(car, error):
create_message_box(f'Could not insert {car}: {error}') # or whatever
Then:
# ...
try:
res = db.execute('insert into car_park values (?)', (car,))
except sqlite3.IntegrityError as e:
handle_insert_car_error(car, e)
I want to update one table in mysql which has 3 rows
what i want is to update any row with update command but this has to be happened only when there exists a particular row
i.e.if i update it like updatedata = "update table12 set name='Dhiraj', city='Delhi' where id=25"
then it should give me an error
Here is my code:
import pymysql
db = pymysql.connect('localhost','root','','firstdb')
print("database connected successfully")
cur = db.cursor()
updatedata = "update table12 set name='Dhiraj', city='delhi' where id=25"
if updatedata:
try:
cur.execute(updatedata)
db.commit()
print("Data updated successfully...")
except:
print("Something went wrong!")
else:
print("There is no any data you entered!")
cur.execute() returns the number of affected rows:
https://pymysql.readthedocs.io/en/latest/modules/cursors.html#pymysql.cursors.Cursor.execute
So you should be able to do something like:
updated_rows = cur.execute(updatedata)
if updated_rows > 0:
print("success")
else:
print("no matching rows")
This updates all rows based on a condition over the same table
UPDATE tbl
SET field_to_update = CASE
WHEN (SELECT COUNT(*) FROM (SELECT * FROM tbl) AS copy WHERE copy.field=<condition> HAVING COUNT(*)>0) THEN "this_value_if_true"
ELSE field_to_update
END
I'm trying to read lines from stdin, and insert data from those lines into a PostgreSQL db, using a plpythonu stored procedure.
When I call the procedure under Python 3, it runs (consuming a serial value for each line read),
but stores no data in the db.
When I call the same procedure from psql, it works fine, inserting a single line in the db.
For example:
Action: Run SELECT sl_insert_day('2017-01-02', '05:15'); from within psql as user jazcap53
Result: day inserted with day_id 1.
Action: Run python3 src/load/load_mcv.py < input.txt at the command line
Result: nothing inserted, but 2 serial day_id's are consumed.
Action: Run SELECT sl_insert_day('2017-01-03', '06:15'); from within psql as user jazcap53
Result: day inserted with day_id 4.
file: input.txt:
DAY, 2017-01-05, 06:00
DAY, 2017-01-06, 07:00
Output:
('sl_insert_day() succeeded',)
('sl_insert_day() succeeded',)
I'm running Fedora 25, Python 3.6.0, and PostgreSQL 9.5.6.
Thank you very much to anyone who can help me with this!
Below is an MCV example that reproduces this behavior. I expect my problem is in Step 8 or Step 6 -- the other Steps are included for completeness.
The Steps used to create the MCV:
Step 1) Create database:
In psql as user postgres,
CREATE DATABASE sl_test_mcv;
Step 2) Database init:
file: db/database_mcv.ini
[postgresql]
host=localhost
database=sl_test_mcv
user=jazcap53
password=*****
Step 3) Run database config:
file: db/config_mcv.py
from configparser import ConfigParser
def config(filename='db/database_mcv.ini', section='postgresql'):
parser = ConfigParser()
parser.read(filename)
db = {}
if parser.has_section(section):
params = parser.items(section)
for param in params:
db[param[0]] = param[1]
else:
raise Exception('Section {} not found in the {} file'.format(section, filename))
return db
Step 4) Create table:
file: db/create_tables_mcv.sql
DROP TABLE IF EXISTS sl_day CASCADE;
CREATE TABLE sl_day (
day_id SERIAL UNIQUE,
start_date date NOT NULL,
start_time time NOT NULL,
PRIMARY KEY (day_id)
);
Step 5) Create language:
CREATE LANGUAGE plpythonu;
Step 6) Create procedure:
file: db/create_procedures_mcv.sql
DROP FUNCTION sl_insert_day(date, time without time zone);
CREATE FUNCTION sl_insert_day(new_start_date date,
new_start_time time without time zone) RETURNS text AS $$
from plpy import spiexceptions
try:
plan = plpy.prepare("INSERT INTO sl_day (start_date, start_time) \
VALUES($1, $2)", ["date", "time without time zone"])
plpy.execute(plan, [new_start_date, new_start_time])
except plpy.SPIError, e:
return "error: SQLSTATE %s" % (e.sqlstate,)
else:
return "sl_insert_day() succeeded"
$$ LANGUAGE plpythonu;
Step 7) Grant privileges:
file: db/grant_privileges_mcv.sql
GRANT SELECT, UPDATE, INSERT, DELETE ON sl_day TO jazcap53;
GRANT USAGE ON sl_day_day_id_seq TO jazcap53;
Step 8) Run procedure as python3 src/load/load_mcv.py < input.txt:
file: src/load/load_mcv.py
import sys
import psycopg2
from spreadsheet_etl.db.config_mcv import config
def conn_exec():
conn = None
try:
params = config()
conn = psycopg2.connect(**params)
cur = conn.cursor()
last_serial_val = 0
while True:
my_line = sys.stdin.readline()
if not my_line:
break
line_list = my_line.rstrip().split(', ')
if line_list[0] == 'DAY':
cur.execute('SELECT sl_insert_day(\'{}\', \'{}\')'.
format(line_list[1], line_list[2]))
print(cur.fetchone())
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
if __name__ == '__main__':
conn_exec()
Do conn.commit() after cur.close()
Sorry if this question is stupid, I am 2 days into learning python
I have been beating my head against a wall trying to understand why my python script can run SELECT statements but not UPDATE or DELETE statements.
I believe this would be a MySQL issue and not a Python issue but I am no longer able to troubleshoot
pcheck.py
import re
import time
import json
import MySQLdb
import requests
from array import *
conn = MySQLdb.connect([redacted])
cur = conn.cursor()
sql1 = "SELECT pkey,pmeta FROM table1 WHERE proced = 0 LIMIT 1"
cur.execute(sql1)
row = cur.fetchone()
while row is not None:
print "row is: ",row[0]
rchk = [
r"(SHA256|MD5)",
r"(abc|def)"
]
for trigger in rchk:
regexp = re.compile(trigger)
pval = row[1]
if regexp.search(pval) is not None:
print "matched on: ",row[0]
sql2 = """INSERT INTO table2 (drule,dval,dmeta) VALUES('%s', '%s', '%s')"""
try:
args2 = (trigger, pval, row[1])
cur.execute(sql2, args2)
print(cur._last_executed)
except UnicodeError:
print "pass-uni"
break
else:
pass
sql3 = """UPDATE table1 SET proced=1 WHERE pkey=%s"""
args3 = row[0]
cur.execute(sql3, args3)
print(cur._last_executed)
row = cur.fetchone()
sql3 = """DELETE FROM table1 WHERE proced=1 AND last_update < (NOW() - INTERVAL 6 MINUTE)"""
cur.execute(sql3)
print(cur._last_executed)
cur.close()
conn.close()
print "Finished"
And the actual (and suprisingly expected) output:
OUTPUT
scrape#:~/python$ python pcheck.py
row is: 0GqQ0d6B
UPDATE table1 SET proced=1 WHERE pkey='0GqQ0d6B'
DELETE FROM table1 WHERE proced=1 AND last_update < (NOW() - INTERVAL 6 MINUTE)
Finished
However, the database is not being UPDATED. I checked that the query was making it to MySQL:
MySQL Log
"2015-12-14 22:53:56","localhost []","110","0","Query","SELECT `pkey`,`pmeta` FROM `table1` WHERE `proced`=0 LIMIT 200"
"2015-12-14 22:53:57","localhost []","110","0","Query","UPDATE `table1` SET `proced`=1 WHERE `pkey`='0GqQ0d6B'"
"2015-12-14 22:53:57","localhost []","110","0","Query","DELETE FROM table1 WHERE proced=1 AND last_update < (NOW() - INTERVAL 6 MINUTE)"
However proced value for row 0GqQ0d6B is still NOT 1
If I make the same queries via Sqlyog (logged in as user) the queries work as expected.
These kind of issues can be very frustrating. You sure there's no extra spaces here?
print "row is:*"+row[0]+"*"
Perhaps comment out the
for trigger in rchk:
section, and sprinkle some print statements around?
As the commenter Bob Dylan was able to deduce the cursor needed to be committed after the change.
I am trying to check if a row exist with the same Name my database with python and can't quite get it here is what I am trying: (I know the connection is wokring)
try:
cursor.execute("SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name"), (item_name)
catch:
print "it does not exist"
Can someone help me out here
Thanks
First of all you have a wrong syntax in your code. Python doesn't have a try...catch block. It has try...except block which is used like this:
try:
# something here
except:
# something here
MySQL does not return an error when you use SELECT command. However there are two different ways you can find out if it returned something or not.
PYTHON 2.7
cursor.execute(
"SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name",
(item_name,)
)
# gets the number of rows affected by the command executed
row_count = cursor.rowcount
print "number of affected rows: {}".format(row_count)
if row_count == 0:
print "It Does Not Exist"
PYTHON 3+
cursor.execute(
"SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name",
(item_name,)
)
# gets the number of rows affected by the command executed
row_count = cursor.rowcount
print ("number of affected rows: {}".format(row_count))
if row_count == 0:
print ("It Does Not Exist")
Another way to do this would be to fetch the statement and check if it is empty:
# execute statement same as above
msg = cursor.fetchone()
# check if it is empty and print error
if not msg:
print 'It does not exist'
This is my first answer, so I don't know how to style the code in the answer properly, it also seems messy because of that. Sorry for that.
Also i use Python 3 and pymysql, so there may be some syntax error but I have tried to write the code according to python 2.7 from what I could remember about it.
EDIT (5/1/2020)
Thanks to #Arishta for pointing out that the first method will require you to fetch all rows before using row_count. i.e adding cursor.fetchall() before the row_count = cursor.rowcount
cursor.execute(
"SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name",
(item_name,)
)
# Add THIS LINE
results = cursor.fetchall()
# gets the number of rows affected by the command executed
row_count = cursor.rowcount
print("number of affected rows: {}".format(row_count))
if row_count == 0:
print("It Does Not Exist")
Use the cursor.fetchone() if you only care if the record exists or not.
If you want to check for empty results, try if cur.description is None:
if cursor.description is None:
# No recordset for INSERT, UPDATE, CREATE, etc
pass
else:
# Recordset for SELECT
As well as:
exist = cursor.fetchone()
if exist is None:
... # does not exist
else:
... # exists
If you are running a statement that would never return a result set
(such as INSERT without RETURNING, or SELECT ... INTO), then you
do not need to call .fetchall(); there won't be a result set for
such statements. Calling .execute() is enough to run the statement.
cursor.execute("SELECT * FROM userinfo WHERE User_Name=%s",(userid,))
data="error" #initially just assign the value
for i in cursor:
data=i #if cursor has no data then loop will not run and value of data will be 'error'
if data=="error":
print("User Does not exist")
else:
print("User exist")