ODI - Call SQLLDR via Jython on Windows Shell - oracle

I'm testing some interfaces with Oracle Data Integrator 11g on Windows 7.
All the interfaces use the LKM MSSQL to Oracle (BCP/SQLLDR), while running them I got an error on the "Call SQLLDR via Jython" command. After some invesetigation I found that the root of the problem was the following line of code:
exitCode = os.system(sqlldr + " control=" + tempSessionFilePrefix + ".ctl log=" + tempSessionFilePrefix + ".log " + "userid=" + "<% out.print(odiRef.getInfo("DEST_USER_NAME")); %>" + "/" + "<% out.print(odiRef.getInfo("DEST_PASS")); %>" + tnsnameOption + " > " + tempSessionFilePrefix +".out" );
It should run on the Windows Shell a string in the form of:
sqlldr control=control_file.ctl log=log_file.log userid=ODI_STAGE/ODI_STAGE > shell_output.out
I did run the string generated directly on the command prompt and it worked without any problem.
So after playing a bit with the code, I couldn't make the os.system working so I replaced it with subprocess.call. I also have to remove the last part of the string where it attempts to save the ouput of the command prompt (> shell_output.out) to make the whole thing work:
exitCode = subprocess.call([sqlldr, "control=" + tempSessionFilePrefix + ".ctl", "log=" + tempSessionFilePrefix + ".log", "userid=" + "<% out.print(odiRef.getInfo("DEST_USER_NAME")); %>" + "/" + "<% out.print(odiRef.getInfo("DEST_PASS")); %>" + tnsnameOption], shell=True);
This one works smoothly.
Regarding the shell output, I suspect that the problem is the string part that starts with the '>' charcater that is parsed as part of the arguments of SQLLDR instead of a command to the prompt.
Now, while I can live without it, I would like to ask if someone knows any simple workaround to get also the shell output.

Ok I was finally able to get also the shell output.
I edited the "Call SQLLDR via Jython" command with the following:
from __future__ import with_statement
import subprocess
...
with open(tempSessionFilePrefix + ".out", "w") as fout:
exitCode = subprocess.call([sqlldr, "control=" + tempSessionFilePrefix + ".ctl", "log=" + tempSessionFilePrefix + ".log", "userid=" + "ODI_STAGE" + "/" + "<#=snpRef.getInfo("DEST_PASS") #>" + tnsnameOption], stdout=fout, shell=True);
Now everything work as intended.

Related

Windows cmd: piping python 3.5 py file results works but pyinstaller exe's leads to UnicodeEncodeError

I am somewhat out of options here...
# -*- coding: utf-8 -*-
print(chr(246) + " " + chr(9786) + " " + chr(9787))
print("End.")
When I run the code mentioned above in my Win7 cmd window, I get the results depending on the way I invoke it:
python.exe utf8.py
-> ö ☺ ☻
python.exe utf8.py >test.txt
-> ö ☺ ☻ (in file)
utf8.exe
-> ö ☺ ☻
utf8.exe >test.txt
RuntimeWarning: sys.stdin.encoding == 'utf-8', whereas sys.stdout.encoding == 'cp1252', readline hook consumer may assume they are the same
Traceback (most recent call last):
File "Development\utf8.py", line 15, in <module>
print(chr(246) + " " + chr(9786) + " " + chr(9787))
File "C:\python35\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u263a' in position
Messing around with win_unicode_console doesn't help either. In the end, I get the same results.
PYTHONIOENCODING=utf-8
is set. But it seems, that when using PyInstaller, the parameter is ignored for stdout.encoding:
print(sys.stdout.encoding)
print(sys.stdout.isatty())
print(locale.getpreferredencoding())
print(sys.getfilesystemencoding())
print(os.environ["PYTHONIOENCODING"])
Output:
python.exe utf8.py > test.txt
utf-8
False
cp1252
mbcs
utf-8
utf8.exe >test.txt
cp1252
False
cp1252
mbcs
utf-8
The questions are: How does that happen? And: How can I fix that?
codecs.getwriter([something])(sys.stdout)
seems to be discouraged because it may lead to modules with broken output. Or is it possible to force that to utf-8 in case we did a check for a tty? Better: How to fix that in PyInstaller?
Thanks in advance...
Thanks to eryksun, the following workaround is working:
STDOUT_ENCODING = str(sys.stdout.encoding)
try:
PYTHONIOENCODING = str(os.environ["PYTHONIOENCODING"])
except:
PYTHONIOENCODING = False
# Remark: In case the stdout gets modified, it will only append all information
# that has been written into the pipe until that very moment.
if sys.stdout.isatty() is False:
print("Program is running in piping mode. (sys.stdout.isatty() is " + str(sys.stdout.isatty()) + ".)")
if PYTHONIOENCODING is not False:
print("PYTHONIOENCODING is set to a value. ('" + str(PYTHONIOENCODING) + "')")
if str(sys.stdout.encoding) != str(PYTHONIOENCODING):
print("PYTHONIOENCODING is differing from stdout encoding. ('" + str(PYTHONIOENCODING) + "' != '" + STDOUT_ENCODING + "'). This should normally not happen unless the PyInstaller setup is still broken. Setting hard utf-8 workaround.")
sys.stdout = open(sys.stdout.fileno(), 'w', encoding='utf-8', closefd=False)
print("PYTHONIOENCODING was differing from stdout encoding. ('" + str(PYTHONIOENCODING) + "' != '" + STDOUT_ENCODING + "'). This should normally not happen unless PyInstaller is still broken. Setting hard utf-8 workaround. New encoding: '" + str(PYTHONIOENCODING) + "'.", "D")
else:
print("PYTHONIOENCODING is equal to stdout encoding. ('" + str(PYTHONIOENCODING) + "' == '" + str(sys.stdout.encoding) + "'). - All good.")
else:
print("PYTHONIOENCODING is set False. ('" + str(PYTHONIOENCODING) + "'). - Nothing to do.")
else:
print("Program is running in terminal mode. (sys.stdout.isatty() is " + str(sys.stdout.isatty()) + ".) - All good.")
Trying to set up a new PyInstaller-Environment to see if that fixes it from the start next.

SELECT * INTO Incomplete Query Clause

I seem to be doing something wrong in my OleDbCommand, but I don't know what it is. I am trying to create another table in my access database that is exactly the same as the first but with a different name, by copying everything from one and using SELECT INTO. I don't know why it doesn't work.
OleDbCommand copyAttendanceCommand = new OleDbCommand("SELECT * INTO '" + "Attendance " + DateTime.Now.Day + "/" + DateTime.Now.Month + "/" + DateTime.Now.Year + "' FROM Attendance",loginForm.connection);
copyAttendanceCommand.ExecuteNonQuery();
The Error message that I get says "Syntax error in query. Incomplete query clause." Does anyone know what that means?
Table or field names with spaces are not specified with '' around them, but with square brackets.
Your command should be:
"SELECT * INTO [Attendance " + DateTime.Now.Day + "/" + DateTime.Now.Month + "/"
+ DateTime.Now.Year + "] FROM Attendance"
You may even format your date to make the code more readable:
string today = DateTime.Today.ToString("d'/'M'/'yyyy");
string sql ="SELECT * INTO [Attendance " + today + "] FROM Attendance";
OleDbCommand copyAttendanceCommand = new OleDbCommand(sql, loginForm.connection);
copyAttendanceCommand.ExecuteNonQuery();

How to insert line break in a return statement for D3

I have the following code d3 code:
tooltip.select("#popupCount").text(function(){
if (varToGraph == "rough_top_cost"){
return " " + textValue + ": $" + addCommas(allCountyData[countyName][varToGraph]) + "\n" +
"Count:"
}})
I want the word count to appear on a new line. However, the above code results in everything being on one line. How can I get the output to be on two lines?
Thanks,
AH
Untested answer, but FWIW this may get close;
tooltip.select("#popupCount").html(function(){
if (varToGraph == "rough_top_cost"){
return " " + textValue + ": <br/>$" + addCommas(allCountyData[countyName][varToGraph]) + "\n" +
"Count:"
}})
Working from the example provided on page 80 of D3 Tips and Tricks which includes tooltips with line breaks.
Uses html element instead of text which allows line breaks. Check out the document for more detail.

Capturing a screenshot

I'm unable to figure out how to capture a screenshot when a test fails in watir. Please any help/examples?
Here is an exaample of my code
testName = "Entered 000000 - Invalid Unit Number"
browser.text_field(:name => 'unitNumber').set '000000'
browser.button(:name => "OpRetrieve").click
message=browser.text_field(:id => 'messages').text
if message == "Invalid Unit Number"
f1.puts "PASSED #" + testId.to_s + ": " + testName
else
f1.puts "FAILED #" + testId.to_s + ": " + testName + ". Message: " + message
"Capturd screenshot"
end
testId=testId+1
This should do it:
browser.screenshot.save 'screenshot.png'
For more information see http://watir.github.io/docs/screenshots/
This works for phantomjs, I guess it should work for any driver.
browser.driver.screenshot.save 'wtf.png'
Here's a working example I made before. It does something like:
page.driver.render 'test.pdf'
You can achieve like this also.
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("C:\\screenShot1.png"));
for using these you need to import below classes
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.TakesScreenshot;

QUrl containing parentheses

Our application is a 32 bit application. When it is installed in windows 7 64bit, typically it installs at “C:\Program Files (x86)”, instead of “C:\Program Files”. We are constructing a Url based on the install location and pass it around as part of a web service. We are constructing the Url like this:
ppmPath = "http://" + ipAddress + ":13007/" + folder + ".ppm" + "?filePath="
+ applicationDirPath + "/" + FIRMWARE;
QUrl ppmURL( ppmPath, QUrl::TolerantMode );
ppmPath = QString( ppmURL.toEncoded() );
The variable types and meaning are usual.
Since “applicationDirPath” for Windows 7 64 bit contains one closing bracket “)” - in the “(x86)” substring – apparently the URL is broken. If we install it to any other location, it works perfectly, even though the location has any other special character.
How to deal with “)” character in the URL, so that is is not broken?
From the documentation it doesn't look like parentheses are automatically encoded by QUrl, even in tolerant mode. If you first wrap your URL in a QString and then replace all ( characters with "%28" and all ) characters with "%29" then it should behave like you expect.
QString ppmPath = QString("http://" + ipAddress + ":13007/" + folder + ".ppm" + "?filePath="
+ applicationDirPath + "/" + FIRMWARE);
QUrl ppmURL( ppmPath, QUrl::TolerantMode );
ppmPath = QString( ppmURL.toEncoded() );
ppmPath.replace(QChar('('), "%%28");
ppmPath.replace(QChar(')'), "%%29");
I'm not 100% sure the double-% needs to be there, but I remember having trouble with that in the past. Try it both ways.
Alternatively, you could try playing with QUrl::toPercentEncoding() and skip the constructor altogether. It appears to convert parentheses.
QUrl ppmURL(QString("http://" + ipAddress + ":13007/" + folder + ".ppm"), QUrl::TolerantMode );
QString filepath = QUrl::toPercentEncoding(applicationDirPath + "/" + FIRMWARE);
ppmUrl.addEncodedQueryItem("filepath", filepath.toLocal8Bit());
ppmPath = QString( ppmURL.toEncoded() );

Resources