flask sqlalchemy update sql raw command does not provide any response - python

I'm trying to perform an update using flask-sqlalchemy but when it gets to the update script it does not return anything. it seems the script is hanging or it is not doing anything.
I tried to wrap a try catch on the code that does not complete but there are no errors.
I gave it 10 minutes to complete the update statement which only updates 1 record and still, it will not do anything for some reason.
When I cancel the script, it provides an error Communication link failure (0) (SQLEndTran) but I don't think this is the root cause of the error because on the same script, I have other sql scripts that works ok so the connection to db is good
what my script does is get some list of filenames that I need to process (I have no issues with this). then using the retrieved list of filenames, I will look into the directory to check if the file exists. if it does not exists, I will update the database to tag the file as it is not found. this is where I get the issue, it does not perform the update nor provide an error message of some sort.
I even tried to create a new engine just for the update script, but still I get the same behavior.
I also tried to print out the sql script first in python before executing. I ran the printed sql command on my sql browser and it worked ok.
The code is very simple, I'm not really sure why it's having the issue.
#!/usr/bin/env python3
from flask_sqlalchemy import sqlalchemy
import glob
files_directory = "/files_dir/"
sql_string = """
select *
from table
where status is null
"""
# ommited conn_string
engine1 = sqlalchemy.create_engine(conn_string)
result = engine1.execute(sql_string)
for r in result:
engine2 = sqlalchemy.create_engine(conn_string)
filename = r[11]
match = glob.glob(f"{files_directory}/**/{filename}.wav")
if not match:
print('no match')
script = "update table set status = 'not_found' where filename = '" + filename + "' "
engine2.execute(script)
engine2.dispose()
continue
engine1.dispose()

it appears that if I try to loop through 26k records, the script doesn't work. but when I try to do by batches of 2k records per run, then the script will work. so my sql string will become (added top 2000 on the query)
sql_string = """
select top 2000 *
from table
where status is null
"""
it's manual yeah, but it works for me since I just need to run this script once. (I mean 13 times)

Related

pandas.tocsv() format issue (?) resulting in error when using psycopg2 copy_from

Overview:
I have a function in an external file that returns a dataframe that I then save to a csv with:
df.to_csv('filepath.csv', na_rep="0", index=False)
I then try to import the csv into a postgres table using the pyscopg2 function copy_from:
try:
connect = psycopg2.connect(database = "", user = "", password = "", host = "", port = "")
except:
print("Could not connect to database")
cursor = connect.cursor()
with open("filepath", 'r') as open_csv:
next(open_csv)
try:
cursor.copy_from(open_csv, sep=",")
connect.commit()
print("Copy Complete")
except:
print("Copy Error")
cursor.close()
This results in a copy error exception in the code above (so no real detail) but there are some weird caveats:
For some reason, if I open the csv in libre office and manually save it as a text csv and then run just the above psycopg2 copy_from process, the copy works and there are no issues. So for whatever reason, in the eyes of psycopg2 copy_from, something is off with the to.csv() write that gets fixed if I just manually save the file. Manually saving the csv does not result in any visual changes so what is happening here?
Also, the above psycopg2 code snippet works without error in another file in which all dataframe manipulation is contained within the single file where the to.csv() is completed. So something about returning a dataframe from a function in an external file is off?
Fwiw, when debugging, the issue came up on the .copy_from() line so the issue has something to do with csv formatting and I cannot figure it out. I found a workaround with sqlalchemy but would like to know what I am missing here instead of ignoring the problem.
In the postgres error log, the error is: "invalid input syntax for type integer: "-1.0". This error is occurring in the last column of my table where the value is set as an INT and in the csv, the value is -1 but it is being interpreted as -1.0. Where I am confused is that if I use a COPY query to directly input the csv file into postgres, it does not have a problem. Why does it interpret the value as -1.0 through psycopg2 but not directly in postgres?
This is my first post so if more detail is needed let me know - thanks in advance for the help

inserting data to postgres using python

below is a sample of code that i am using to push data from one postgres server to another postgres server. I am trying to move 28 Million records. This worked perfectly with sql server to postgres, but now that it's postgres to postgres it is hanging on line
sourcecursor.execute('select * from "schema"."reallylargetable"; ')
it never reaches any of the other statements to get to the Iterator.
I get this message:
psycopg2.DatabaseError: out of memory for query result ad the select query statement.
#cursors for aiods and ili#
sourcecursor = sourceconn.cursor()
destcursor= destconn.cursor()
#name of temp csv file
filenme= 'filename.csv'
#defenition that uses fetchmany to iterate through data in batch. default
value is in 10000#
def ResultIterator(cursor, arraysize=1000):
'iterator using fetchmany and consumes less memory'
while True:
results = cursor.fetchmany(arraysize)
if not results:
break
for result in results:
yield result
#set data for the cursor#
print("start get data")
#it is not going past the line below. it errors at with out of memory for query result
sourcecursor.execute('select * from "schema"."reallylargetable"; ')
print("iterator")
dataresults= ResultIterator(sourcecursor)
*****do something with dataresults *********
Please change this line:
sourcecursor = sourceconn.cursor()
to name your cursor (use whatever name pleases you):
sourcecursor = sourceconn.cursor('mysourcecursor')
What this does is direct psycopg2 to open a postgresql server-side named cursor for your query. Without a named cursor on the server side, psycopg2 attempts to grab all rows when executing the query.

Mysql 8.0 syntax error check manual for proper syntax

what's wrong with this line of code?
whenever I run it it shows syntax error 'mysql' check the corresponding server version.
import mysql.connector
import builtins
import importlib.util
import os
v=os.getcwd()
loc=""
for i in v:
if i == "\\":
loc += "/"
else:
loc += i
print(loc)
def crt():
m=mysql.connector.connect(host="localhost",user="root",passwd="****")
mc=m.cursor()
mc.execute("create database if not exists mydb")
crt()
m=mysql.connector.connect(host="localhost",user="root",passwd="****",database="mydb")
mc=m.cursor()
mc.execute("source "+loc+"/mydb.sql;")
normally for mysql when I apply the following code it works.
use mydb;
source C:\Users\15fri\OneDrive\Desktop\s3ts\mydb.sql
as for the for loop section in the previous code I converted the backslashes to forward slashes since some time the location in the code even works with forward slashes..
Your problem is probably that source is not an SQL command and that it's only available from within the mySQL CLI.
Try reading the script file and passing its contents as a string to mc.execute()
In response to your comment CrazY JoN, I'm no Python programmer but I was thinking of something like this:
sql_script_file = open("source "+loc+"/mydb.sql;",'r')
sql_script = sql_script_file.read()
sql_commands = sql_script.split(";") # assuming the commands in the script have to be executed one at a time
for cmd in sql_commands:
mc.execute(cmd)

Python -printing the sql statement record count in the log file

I am currently using the python program for inserting the record and i am using the below statement.The issue is i am trying to print the no of of record inserted in the log file but it is printing only 0 but i can see the inserted record count in the console while running the program Can you help me to print the record count in the log file
Also i know that redirecting the python program to > file can have the record count but i want to bring all the details in the same log file after the insert record statement is done as i am using loop for different statement.
log="/fs/logfile.txt"
log_file = open(log,'w')
_op = os.system('psql ' + db_host_connection + ' -c "insert into emp select * from emp1;"')
print date , "printing" , _op
You should probably switch to a "proper" python module for postgresql interactions.
Haven't used postgresql in python before, but one of the first search engine hits leads to:
http://initd.org/psycopg/docs/usage.html
You could then do something along the following lines:
import psycopg2
conn = psycopg2.connect("dbname=test user=postgres")
# create a cursor for interaction with the database
cursor = conn.cursor()
# execute your sql statement
cursor.execute("insert into emp select * from emp1")
# retrieve the number of selected rows
number_rows_inserted = cursor.rowcount
# commit the changes
conn.commit()
This should also make things significantly faster than using an os.system call(s), especially if you're planning to execute multiple statements.

Returning Output of Python CGI MySQL Script

I'm very new to Python and MySQL and this is my first Stack question. So, apologies in advance if I'm missing something obvious. But, I really did try to research this before asking.
I'm trying to learn the basics of Python, MySQL, and CGI scripting. To that end, I've been reading tutorials at http://www.tutorialspoint.com/python/python_cgi_programming.htm and http://www.tutorialspoint.com/python/python_database_access.htm, among others.
I'm trying to have a CURL GET or Python Requests GET call a Python CGI script on a test server. That Python CGI script would then perform a Read action on a local MySQL database and return the results to CURL or to Python Requests.
The Python CGI script I've created outputs the MySQL Read data perfectly to the terminal on the remote test server. But, it won't return that output to the CURL or to the Python Requests that triggered the CGI script.
This is the Python CGI script I've cobbled together:
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Prepare SQL query to INSERT a record into the database.
sql = "SELECT * FROM EMPLOYEE \
WHERE INCOME > '%d'" % (1000)
try:
# Execute the SQL command
cursor.execute(sql)
# Fetch all the rows in a list of lists.
results = cursor.fetchall()
for row in results:
fname = row[0]
lname = row[1]
age = row[2]
sex = row[3]
income = row[4]
# Now print fetched result
print "fname=%s,lname=%s,age=%d,sex=%s,income=%d" % \
(fname, lname, age, sex, income )
except:
print "Error: unable to fetch data"
# disconnect from server
db.close()
My guess is that I need to somehow pass the data from the SQL query back to Python or back to the requesting process through some sort of Return or Output statement. But, all my best efforts to research this have not helped. Can anyone point me in the right direction? Many thanks for any help!
Marc :-)
First, as per the CGI tutorial you link, you need to output the content type you are working with:
print "Content-type: text/plain\r\n\r\n",
If you don't at least have the newlines in there, HTTP clients will think your content is supposed to be part of the headers and get confused, they will probably assume the document you asked for is empty.
Next, you need a CGI server. Python comes with one. Place your script in a subdirectory called cgi-bin and run this command (from the parent directory):
python -m CGIHTTPServer
The url to call will look something like this:
curl http://localhost:8000/cgi-bin/cgitest.py

Categories