Can't merge table using cx_oracle in python - python

I'm trying to merge two tables by using cx_oracle.
The following sql language works at sql developer tools:
MERGE INTO ASBODS_SDDM_SCHEMA.EULA_DATA E
USING (SELECT * FROM ASBODS_SDDM_SCHEMA.EULA_STG_DATA) ES
ON (E.MASTER_METER_NBR = ES.MASTER_METER_NBR AND E.MASTER_ACCOUNT_NBR = ES.MASTER_ACCOUNT_NBR AND
E.METER_NBR = ES.METER_NBR AND E.ACCOUNT_NBR = ES.ACCOUNT_NBR AND E.EULA_DATA_TYPE_CD = ES.EULA_STG_DATA_TYPE_CD)
WHEN MATCHED THEN
UPDATE SET
E.ACCEPTED_DT = ES.ACCEPTED_DT ,
E.DECLN_OF_CONSENT_FLG = ES.DECLN_OF_CONSENT_FLG ,
E.EULA_VERSION_NBR = ES.EULA_VERSION_NBR,
E.SOFTWARE_VERSION_NBR = ES.SOFTWARE_VERSION_NBR,
E.COMPANY_NM = ES.COMPANY_NM ,
E.MACH_ID = ES.MACH_ID ,
E.LOAD_DT = ES.LOAD_DT
WHERE
E.MASTER_METER_NBR = ES.MASTER_METER_NBR AND E.MASTER_ACCOUNT_NBR = ES.MASTER_ACCOUNT_NBR AND
E.METER_NBR = ES.METER_NBR AND E.ACCOUNT_NBR = ES.ACCOUNT_NBR AND E.EULA_DATA_TYPE_CD = ES.EULA_STG_DATA_TYPE_CD
But when I insert this sql into cx_Orcale:
import cx_Oracle
try:
con = cx_Oracle.connect('username/pwd#server')
cursor = con.cursor()
cursor.execute(''' MERGE INTO ASBODS_SDDM_SCHEMA.EULA_DATA E
USING (SELECT * FROM ASBODS_SDDM_SCHEMA.EULA_STG_DATA) ES
ON (E.MASTER_METER_NBR = ES.MASTER_METER_NBR AND E.MASTER_ACCOUNT_NBR = ES.MASTER_ACCOUNT_NBR AND
E.METER_NBR = ES.METER_NBR AND E.ACCOUNT_NBR = ES.ACCOUNT_NBR AND E.EULA_DATA_TYPE_CD = ES.EULA_STG_DATA_TYPE_CD)
WHEN MATCHED THEN
UPDATE SET
E.ACCEPTED_DT = ES.ACCEPTED_DT ,
E.DECLN_OF_CONSENT_FLG = ES.DECLN_OF_CONSENT_FLG ,
E.EULA_VERSION_NBR = ES.EULA_VERSION_NBR,
E.SOFTWARE_VERSION_NBR = ES.SOFTWARE_VERSION_NBR,
E.COMPANY_NM = ES.COMPANY_NM ,
E.MACH_ID = ES.MACH_ID ,
E.LOAD_DT = ES.LOAD_DT
WHERE
E.MASTER_METER_NBR = ES.MASTER_METER_NBR AND E.MASTER_ACCOUNT_NBR = ES.MASTER_ACCOUNT_NBR AND
E.METER_NBR = ES.METER_NBR AND E.ACCOUNT_NBR = ES.ACCOUNT_NBR AND E.EULA_DATA_TYPE_CD = ES.EULA_STG_DATA_TYPE_CD
''')
con.commit()
except cx_Oracle.DatabaseError as e:
print('There is problem with sql', e)
finally:
if cursor:
con.commit()
cursor.close()
if con:
con.close()
It has long time no feedback in linux, seems it is running all the time,and not work.
Any friend can help?

Did you commit in the tool session? Maybe the tables are locked.

Related

Writing to db from python durables engine

I have been trying to write business rules using durables engine in python. The source code is as below :
import pymysql
import pandas as pd
import datetime
from durable.lang import *
from tickets import *
con = pymysql.connect(host='localhost', user='XXXX', password='XXXX', database='nms')
#df_30min = pd.read_sql('select * from recentalarms where dbinserttime > now() - interval 30 minute', con)
df = pd.read_sql('select * from recentalarms', con)
df_tt = pd.read_sql('select tt_id from ticket', con)
format = "%Y%m%d%H%M%S"
time_before_5min = datetime.datetime.strftime(datetime.datetime.now() - datetime.timedelta(minutes=5), format)
time_before_15min = datetime.datetime.strftime(datetime.datetime.now() - datetime.timedelta(minutes=15), format)
with ruleset('nms'):
#when_all((m.status == 'open') & ( m.instance >= 3) & (m.tt_id == None) & (m.readflag == None ))
def rule_action1(c):
tt_id = Ticket.create(domain_prefix,entity=entity,start_time=down_since,severity=severity)
cursor = con.cursor()
sql_query = f"UPDATE recentalarm SET read_flag = 'true' , tt_id = '{tt_id}' WHERE id = '{alarm_id}';"
cursor.execute(sql_query)
con.commit()
print(f"1. Create ticket Run Completed")
#when_all((m.status == 'close') & ( m.uptime <= time_before_15min) & (m.uptime != None))
def rule_action2(c):
Ticket.resolve(tt_id,time_stmp)
cursor = con.cursor()
sql_query = f"UPDATE recentalarm SET read_flag = 'true' , tt_id = '{tt_id}' WHERE id = '{alarm_id}';"
cursor.execute(sql_query)
con.commit()
print(f"2. Resolve ticket Run Completed")
############some more rules
for i, row in df.iterrows():
stat = row.status.lower()
olt = row.oltname
result = df.iloc[0:i+1]['oltname'] == f'{row.oltname}'
instance_count = int(result.value_counts()[True])
ONTPort = row.ONTParentPort
alarm_id = row.id
entity = row.entity
severity = row.severity
up_since = str(row.eventclosetime)
down_since = str(row.eventime)
try:
post('gponnms', { 'status' : stat , 'instance' : instance_count , 'readflag' : row.read_flag , 'uptime' : up_since , 'downtime' : down_since})
except:
pass
con.close()
I have 2 queries.
In the rule_action I require to update the field back in the sql table for read_flag. This is being done through sql query. Is there another way to update the database other than writing sql query in the action function
My second question is in the last there is post message. I need to understand if this is really required.But if I delete this I get error message. The documentation on durables does not give much insight on it.

Iterate through FOR CURSOR in Python

I just started with coding in Python and I have one problem. I am using ibm_dbi driver.
Here is my sql example:
FOR v AS cur CURSOR FOR
SELECT S.NAME FROM SYSIBM.SYSTABLES AS S
JOIN (SELECT DISTINCT TBNAME FROM SYSIBM.SYSCOLUMNS WHERE CREATOR = 'SOME_SCHEMA_DB') AS C.TBNAME = S.NAME WHERE S.CREATOR = 'SOME_SCHEMA' AND S.TYPE = 'T'
DO
SET TABLE = SCHEMA1 ||'.'||v.Name
...
SELECT 1 INTO TEMP_TABLE FROM SYSIBM.SYSTABLES WHERE TYPE='T' AND CREATOR = SCHEMA1 AND NAME = v.NAME
END FOR;
So far i have in Python:
#make a connection to db
conn = ibm_db_dbi.connect("DATABASE=%s;HOSTNAME=%s,....)
#define a cursor
cur = conn.cursor()
sql="""SELECT S.NAME FROM SYSIBM.SYSTABLES AS S
JOIN (SELECT DISTINCT TBNAME FROM SYSIBM.SYSCOLUMNS WHERE CREATOR = 'SOME_SCHEMA_DB') AS C.TBNAME = S.NAME WHERE S.CREATOR = 'SOME_SCHEMA' AND S.TYPE = 'T'"""
resultSet = cur.execute(sql)
I don't know how to iterate through result from query and set values from the cursor. How to set value for this piece of code
SET TABLE = SCHEMA1 ||'.'||v.Name
...
SELECT 1 INTO TEMP_TABLE FROM SYSIBM.SYSTABLES WHERE TYPE='T' AND CREATOR = SCHEMA1 AND NAME = v.NAME
Tip: get your SQL working outside of python first. Your question shows that query that has syntax mistakes or typos.
To iterate through a result-set from a query, use one of the documented fetch methods for the DBI interface (example, fetchmany() , or fetchall() or others).
Here is a fragment, that uses fetchmany() .
try:
cur = conn.cursor()
sql="""SELECT S.NAME FROM SYSIBM.SYSTABLES AS S
inner JOIN (SELECT DISTINCT TBNAME
FROM SYSIBM.SYSCOLUMNS
WHERE TBCREATOR = 'SOME_SCHEMA') AS C
ON C.TBNAME = S.NAME
WHERE S.CREATOR = 'SOME_SCHEMA'
AND S.TYPE = 'T';"""
cur.execute(sql)
result = cur.fetchmany()
while result:
for i in result:
print(i)
result = cur.fetchmany()
except Exception as e:
print(e)
raise

Updating results from a mysql-connector fetchall

I'm trying to select certain records from the civicrm_address table and update the geocode columns. I use fetchall to retrieve the rows then, within the same loop, I try to update with the results of the geocoder API, passing the civicrm_address.id value in the update_sql statement.
The rowcount after the attempted update and commit is always -1 so I am assuming it failed for some reason but I have yet to figure out why.
import geocoder
import mysql.connector
mydb = mysql.connector.connect(
[redacted]
)
mycursor = mydb.cursor(dictionary=True)
update_cursor = mydb.cursor()
sql = """
select
a.id
, street_address
, city
, abbreviation
from
civicrm_address a
, civicrm_state_province b
where
location_type_id = 6
and
a.state_province_id = b.id
and
street_address is not null
and
city is not null
limit 5
"""
mycursor.execute(sql)
rows = mycursor.fetchall()
print(mycursor.rowcount, "records selected")
for row in rows:
address_id = int(row["id"])
street_address = str(row["street_address"])
city = str(row["city"])
state = str(row["abbreviation"])
myaddress = street_address + " " + city + ", " + state
g = geocoder.arcgis(myaddress)
d = g.json
latitude = d["lat"]
longitude = d["lng"]
update_sql = """
begin work;
update
civicrm_address
set
geo_code_1 = %s
, geo_code_2 = %s
where
id = %s
"""
var=(latitude, longitude, address_id)
print(var)
update_cursor.execute(update_sql, var, multi=True)
mydb.commit()
print(update_cursor.rowcount)
mycursor.close()
update_cursor.close()
mydb.close()
Here is a simpler script:
I have executed the update_sql statement directly in the MySQL workbench and it succeeds. It is not working from Python.
import geocoder
import mysql.connector
try:
mydb = mysql.connector.connect(
[redacted]
)
mycursor = mydb.cursor(dictionary=True)
update_cursor = mydb.cursor()
update_sql = """
begin work;
update
civicrm_address
set
geo_code_1 = 37.3445
, geo_code_2 = -118.5366074
where
id = 65450;
"""
update_cursor.execute(update_sql, multi=True)
mydb.commit()
print(update_cursor.rowcount, "row(s) were updated")
except mysql.connector.Error as error:
print("Failed to update record to database: {}".format(error))
mydb.rollback()
finally:
# closing database connection.
if (mydb.is_connected()):
mydb.close()
I have it working now. I did remove the "begin work" statement but not the multi=True and it wouldn't work. Later I removed the multi=True statement and it works.

python to write data into table error

write python program to create a mysql table and insert data into this table,the program is as follows:
def pre_data_db_manage(type,data):
conn = pymysql.connect(host="localhost", port=3306, user="root", passwd="********", db="facebook_info",charset="utf8")
cur = conn.cursor()
if type == "pre_davi_group_members_data":
is_exist_table_sql = "SHOW TABLES LIKE 'fb_pre_davi_group_members_posts'"
if cur.execute(is_exist_table_sql) == 0:
create_table_sql = '''CREATE TABLE fb_pre_davi_group_members_posts (id bigint not null primary key auto_increment,userID bigint,userName varchar(128),userURL varchar(256),
postTime varchar(128),postText text,postTextLength int,likesCount int,sharesCount int,commentsCount int,postTextPolarity varchar(64),postTextSubjectivity varchar(64))'''
cur.execute(create_table_sql)
r = re.compile(r'^[a-zA-Z0-9]')
for item in data:
if "'" in item["PostText"]:
item["PostText"] = item["PostText"].replace("'"," ")
if "\\" in item["PostText"]:
item["PostText"] = item["PostText"].replace("\\","\\\\")
for i in item["PostText"]:
result = r.match(i)
if result == None:
print("in re")
item['PostText'] = item['PostText'].replace(i, ' ')
if "nan" in item["SharesCount"]:
item["SharesCount"] = 0
if "nan" in item["LikesCount"]:
item["LikesCount"] = 0
if "nan" in item["CommentsCount"]:
item["CommentsCount"] = 0
if "nan" in item["PostTextLength"]:
item["PostTextLength"] = 0
item["PostTextLength"] = int(item["PostTextLength"])
item["LikesCount"] = int(item["LikesCount"])
item["SharesCount"] = int(item["SharesCount"])
item["CommentsCount"] = int(item["CommentsCount"])
if type == "pre_davi_group_members_data":
insert_sql = '''INSERT INTO fb_pre_davi_group_members_posts (userID,userName,userURL,
postTime,postText,postTextLength,likesCount,sharesCount,commentsCount,postTextPolarity,postTextSubjectivity) VALUES
({0},"{1}",'{2}','{3}','{4}',{5},{6},{7},{8},{9},{10})'''.format(item["UserID"],item["UserName"],item["UserURL"],item["PostTime"],item["PostText"],item["PostTextLength"],item["LikesCount"],item["SharesCount"],item["CommentsCount"],item["PostTextPolarity"],item["PostTextSubjectivity"])
print(insert_sql)
try:
cur.execute(insert_sql)
except Exception as e:
print("insert error")
continue
cur.close()
conn.commit()
conn.close()
and write call statement as follows:
type = "pre_davi_group_members_data"
pre_data_db_manage(type, df_list)
however,when execute this program, found that no data have been inserted into table:fb_pre_davi_group_members_posts,
in the mysql order line, write:
select count(*) from fb_pre_davi_group_members_posts;
the result is 0
could you please tell me the reason and how to solve it

Mysql python connector - Row returning null

I am trying to make a very simple select using mysql connector , however , when i try to execute the following commands , the row always returns null , even if there is data to be selected
self.cnx = mysql.connector.connect(user='root', password='123qwe', host='192.168.56.1', database='teste')
self.cursor = self.cnx
self.cursor = self.cnx.cursor()
self.query = ("SELECT cod_produto,quantidade FROM itens_comanda WHERE cod_comanda = %s AND cod_produto = %s")
self.query_data = (comanda,item)
self.cursor.execute(self.query,self.query_data)
row = cursor.fetchone()
if row == None:
return [False,0,0]
else:
for i in row:
return [True,i[0],i[1]]

Categories