What is the correct way to load a dll library in Postgres PL/Python? - postgresql

The following gives an error
drop function testing();
CREATE FUNCTION testing()
RETURNS text
AS $$
import ctypes
try:
ctypes.windll.LoadLibrary("D:\\jcc.dll")
except:
import traceback
plpy.error(traceback.format_exc())
return ''
$$ LANGUAGE plpythonu;
select testing();
Error message:
ERROR: ('Traceback (most recent call last):\n File "<string>", line 5, in __plpython_procedure_testing_1517640\n File "D:\\Python26\\Lib\\ctypes\\__init__.py", line 431, in LoadLibrary\n return self._dlltype(name)\n File "D:\\Python26\\Lib\\ctypes\\__init__.py", line 353, in __init__\n self._handle = _dlopen(self._name, mode)\nWindowsError: [Error 126] The specified module could not be found\n',)
It works fine in a python interpretor.
Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.windll.LoadLibrary("D:\\jcc.dll")
<WinDLL 'D:\jcc.dll', handle 410000 at 1d9cb10>
>>>

"The specified module could not be found" is one of those helpful error messages Windows emits that doesn't always mean what you think it means.
Windows will produce that message if the DLL you tried to load or any dll it depends on could not be found.
Since PostgreSQL runs in its own user account it has a different PATH to that which your interpreter runs in when you're testing. If jcc.dll depends on (say) c:\jccsupportfiles\aaa.dll and c:\jccsupportfiles is on your PATH but not the Pg server's PATH, that would explain your problem.
Try using Dependency Walker (depends.exe) to determine which DLLs your DLL requires and where they are. See if it's a PATH issue.
Rather than messing with the Pg server's PATH, consider just putting all the DLLs required by jcc.dll in the same directory as jcc.dll. IIRC Windows will always look in the same directory as the module it's loading first when it tries to load a module it depends on.

Related

How to set the set_stream_blob_threshold in FIrebird fdb python library?

Trying to migrate data from Firebird DB to MS Sql Server using fdb(2.0.1) and pyodbc. Since there are blobs in the Firebird database which are over 64K, they are being returned as BlobReader objects. Since i would like not to deal with the bytes myself and write them using pyodbc. The docs say that you can turn off the 64K threshold by passing -1 to the cursor.set_stream_blob_threshold. However that doesn't seem to work, since fdb.fbcore.ProgrammingError is thrown...
https://fdb.readthedocs.io/en/v2.0/reference.html#fdb.Cursor.set_stream_blob_treshold
Here is how i call the function:
import fdb
class Firebird:
def __init__(self, db_name: str):
self.__fb_conn = fdb.connect(database=db_name, user='someuser', password='somepass', charset='ISO8859_1')
self.__fb_cursor = self.__fb_conn.cursor()
#change the blob safety threshold to unlimited for troubleshooting
self.__fb_cursor.set_stream_blob_treshold(-1) #doesn't work :(
Here is a stack trace for the error:
(.venv) >python3.8.exe -i
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from commonlibs import Firebird
>>>
>>> fb = Firebird('somedb.fdb')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\user1\dev\commonlibs\Firebird.py", line 13, in __init__
self.__fb_cursor.set_stream_blob_treshold(int(-1)) #doesn't work :(
File "C:\Users\user1\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\fdb\fbcore.py", line 3930, in set_stream_blob_treshold
raise ProgrammingError
fdb.fbcore.ProgrammingError
Per Mark's comment:
I don't know much about the data source and what sort of blobs. It was one of those situations where the other teams guy said: "Hey, here is some data from this partner, let's see what inside"
However when trying to pass the obj.read() value to the pyodbc for BlobReader objects, it did insert some of the blobs. However with a lot of them pyodbc would report this error:
pyodbc.Error: ('HY000', '[HY000] [Microsoft][ODBC SQL Server Driver]Warning: Partial insert/update. The insert/update of a text or image column(s) did not succeed. (0) (SQLPutData); [HY000] [Microsoft][ODBC SQL Server Driver][SQL Server]The text, ntext, or image pointer value conflicts with the column name specified. (7125)')
I was kind hoping i could avoid all this pyodbc and .read() stuff by setting that threshold, but i wonder if the pyodbc error would show up regardless...

Unable to set IPython prompt

I'm running ipython with the following:
c:\python27\scripts\ipython
I'm trying to restore old Python prompt behaviour (">>>") for some reasons.
I've tried to search internet extensively for that purpose, to no avail.
Then I reached for IPython documentation, which turned out to be confusing and unhelpful.
According to http://ipython.readthedocs.io/en/stable/config/details.html
To set the new prompt, assign it to the prompts attribute of the IPython shell:
In [2]: ip = get_ipython()
...: ip.prompts = MyPrompt(ip)
/home/bob >>> # it works
I get the exception that get_ipython is undefined:
[TerminalIPythonApp] ERROR | Exception while loading config file C:\Users\xxx\.ipython\profile_default\ipython_config.py
Traceback (most recent call last):
File "c:\python27\lib\site-packages\traitlets\config\application.py", line 562, in _load_config_files
config = loader.load_config()
File "c:\python27\lib\site-packages\traitlets\config\loader.py", line 457, in load_config
self._read_file_as_dict()
File "c:\python27\lib\site-packages\traitlets\config\loader.py", line 489, in _read_file_as_dict
py3compat.execfile(conf_filename, namespace)
File "c:\python27\lib\site-packages\ipython_genutils\py3compat.py", line 278, in execfile
exec(compiler(scripttext, filename, 'exec'), glob, loc)
File "C:\Users\rgomulk\.ipython\profile_default\ipython_config.py", line 9, in <module>
ip = get_ipython()
NameError: name 'get_ipython' is not defined
Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.
IPython 5.1.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
(With the following complete code in my ipython_config.py:
from IPython.terminal.prompts import Prompts, Token
class MyPrompt(Prompts):
def in_prompt_tokens(self, cli=None):
return [(Token.Prompt, ' >>>')]
ip = get_ipython()
ip.prompts = MyPrompt(ip)
After next round of googling I've added the following line to the config:
from IPython import get_ipython
This time the result was different:
[TerminalIPythonApp] ERROR | Exception while loading config file C:\Users\xxx\.ipython\profile_default\ipython_config.py
Traceback (most recent call last):
File "c:\python27\lib\site-packages\traitlets\config\application.py", line 562, in _load_config_files
config = loader.load_config()
File "c:\python27\lib\site-packages\traitlets\config\loader.py", line 457, in load_config
self._read_file_as_dict()
File "c:\python27\lib\site-packages\traitlets\config\loader.py", line 489, in _read_file_as_dict
py3compat.execfile(conf_filename, namespace)
File "c:\python27\lib\site-packages\ipython_genutils\py3compat.py", line 278, in execfile
exec(compiler(scripttext, filename, 'exec'), glob, loc)
File "C:\Users\rgomulk\.ipython\profile_default\ipython_config.py", line 11, in <module>
ip.prompts = MyPrompt(ip)
AttributeError: 'NoneType' object has no attribute 'prompts'
So the question is twofold:
1. How can I actually set the prompt/restore old prompt behaviour?
2. Why doesn't the code from IPython documentation work? Is that a bug in implementation or documentation?
IPython version and other versions already given in IPython output.
Regards,
Robert
After extensive search (it was really tedious and others are confused as well, especially from distinguishing between startup and configuration scripts) I've found this page: Jupyter prompts
Which led to (working) solution:
from IPython.terminal.prompts import Prompts
from pygments.token import Token
class MyPrompt(Prompts):
def in_prompt_tokens(self, cli=None):
return [(Token.Prompt, '>>> ')]
c.TerminalInteractiveShell.prompts_class = MyPrompt
(Please notice the lack of what seems to be required by official documentation Official IPython docs:
The files typically start by getting the root config object:
c = get_config()
Regards,
Robert
Another possibility - less generic - is to use predefined Prompt class:
from IPython.terminal.prompts import ClassicPrompts
c = get_config()
c.TerminalInteractiveShell.prompts_class = ClassicPrompts

pyglet "Unable to share contexts" exception when running PsychoPy demo twice

PsychoPy looks like just what I need. But I want to use my own development environment (a straightforward IPython prompt combined with the editor of my choice) instead of the provided IDE.
The trouble is that you seem to have to quit Python and relaunch after every PsychoPy run. If for example I cd to the ...../demos/coder/stimuli directory and type run gabor.py it runs fine, but if I then type run gabor.py again I get this exception from pyglet:
C:\snap\PsychoPy2\lib\site-packages\pyglet\window\win32\__init__.pyc in _create(self)
259 if not self._wgl_context:
260 self.canvas = Win32Canvas(self.display, self._view_hwnd, self._dc)
--> 261 self.context.attach(self.canvas)
262 self._wgl_context = self.context._context
263
C:\snap\PsychoPy2\lib\site-packages\pyglet\gl\win32.pyc in attach(self, canvas)
261 self._context = wglext_arb.wglCreateContextAttribsARB(canvas.hdc,
262 share, attribs)
--> 263 super(Win32ARBContext, self).attach(canvas)
C:\snap\PsychoPy2\lib\site-packages\pyglet\gl\win32.pyc in attach(self, canvas)
206 raise RuntimeError('Share context has no canvas.')
207 if not wgl.wglShareLists(share._context, self._context):
--> 208 raise gl.ContextException('Unable to share contexts')
209
210 def set_current(self):
ContextException: Unable to share contexts
Is there some sort of pyglet.cleanup() I can call (analogous to pygame.quit()) to allow PsychoPy scripts to run more than once in the same session? Or other way of avoiding this problem?
I'm using the Standalone PsychoPy distro version 1.81.02, untouched. The problem is not specific to IPython---it also can also be demonstrated from the plain Python prompt if you disable sys.exit and type execfile('gabor.py') twice:
C:\snap\PsychoPy2\Lib\site-packages\PsychoPy-1.81.02-py2.7.egg\psychopy\demos\coder\stimuli>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import sys; sys.exit = lambda x:x
>>> execfile('gabor.py')
0.6560 WARNING Movie2 stim could not be imported and won't be available
1.6719 WARNING Monitor specification not found. Creating a temporary one...
>>>
>>> execfile('gabor.py')
Traceback (most recent call last):
[snip]
File "C:\snap\PsychoPy2\lib\site-packages\pyglet\gl\win32.py", line 208, in attach
raise gl.ContextException('Unable to share contexts')
pyglet.gl.ContextException: Unable to share contexts
I don't know how to undo all the pyglet/psychopy initialisation - neither are really designed for you to do this, so there would be some work here. But I'm not sure it's a good idea anyway to run scripts the way you are doing.
The PsychoPy app itself gets around the by launching each script in a new process. It means that you know the namespace is clean on each run. Running your script on top of the previous one can lead to some really hard-to-find bugs because you don't know in what state the previous script left the memory, graphics card and namespace.
cheers
Jon

iptest3 with IPython

I'm brand new to Python programming and trying to get myself a functional base from which I can run things like the IPython Notebook which looks pretty exciting.
Thus far I have both Python 2.7 and 3.3 from python.org installed in OS X 10.6 (Snow Leopard) as well as ActiveTcl 8.5.13. Almost everything that I've tried thus far works as expected. I'm focused on learning 3.3, but want to have the option of using 2.7 too. I read up in several documents that I need to start gaining access to PyPI packages using a Python package manager and that distribute is the one I should use for 3k. So I installed that according to the documentation I found and it seemed to work fine.
I also installed pip as directed, and a number of others.
At this point, I have:
$ pip freeze
distribute==0.6.34
ipython==0.13.1
nose==1.2.1 (installed after IPython)
pexpect==2.4 (installed after IPython)
pyflakes3k==0.4.3
readline==6.2.4.1 (installed after IPython)
At this point, I'm doing this from ipython.org guidance
And when I did $ easy_install pexpect, I got a bunch of errors:
$ easy_install pexpect
Searching for pexpect
Reading http://pypi.python.org/simple/pexpect/
Reading http://pexpect.sourceforge.net/
Reading http://sourceforge.net/project/showfiles.php?group_id=59762
Best match: pexpect 2.4
Downloading http://pypi.python.org/packages/source/p/pexpect/pexpect-2.4.tar.gz#md5=fe82d69be19ec96d3a6650af947d5665
Processing pexpect-2.4.tar.gz
Writing /var/folders/td/td0Sh8EfGFuMCnKex1v+q++++TI/-Tmp-/easy_install-s4dtyy/pexpect-2.4/setup.cfg
Running pexpect-2.4/setup.py -q bdist_egg --dist-dir /var/folders/td/td0Sh8EfGFuMCnKex1v+q++++TI/-Tmp-/easy_install-s4dtyy/pexpect-2.4/egg-dist-tmp-5h5cg4
File "build/bdist.macosx-10.6-intel/egg/fdpexpect.py", line 36
raise ExceptionPexpect, 'The fd argument is not a valid file descriptor.'
^
SyntaxError: invalid syntax
File "build/bdist.macosx-10.6-intel/egg/FSM.py", line 77
return `self.value`
^
SyntaxError: invalid syntax
File "build/bdist.macosx-10.6-intel/egg/pexpect.py", line 82
except ImportError, e:
^
SyntaxError: invalid syntax
zip_safe flag not set; analyzing archive contents...
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/pexpect-2.4-py3.3.egg/fdpexpect.py", line 36
raise ExceptionPexpect, 'The fd argument is not a valid file descriptor.'
^
SyntaxError: invalid syntax
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/pexpect-2.4-py3.3.egg/FSM.py", line 77
return `self.value`
^
SyntaxError: invalid syntax
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/pexpect-2.4-py3.3.egg/pexpect.py", line 82
except ImportError, e:
^
SyntaxError: invalid syntax
Adding pexpect 2.4 to easy-install.pth file
Installed /Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/pexpect-2.4-py3.3.egg
Processing dependencies for pexpect
Finished processing dependencies for pexpect
That looks bad to me (although I don't yet have the expertise to really interpret it), and so I'm not sure if I have a complete install of pexpect.
After installing nose (before pexpect as per URL above), I tried running iptest and iptest3 from the command line, and both failed to find the command, but after I did easy_install ipython again (after nose), I noticed that this install added iptest3 (as well as ipcluster3 and a few other scripts) to my path, and now my bash shell can find iptest3, but when I run it, I get some more bad-looking output:
$ iptest3
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.3/bin/iptest3", line 9, in <module>
load_entry_point('ipython==0.13.1', 'console_scripts', 'iptest3')()
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/distribute-0.6.34-py3.3.egg/pkg_resources.py", line 343, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/distribute-0.6.34-py3.3.egg/pkg_resources.py", line 2308, in load_entry_point
return ep.load()
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/distribute-0.6.34-py3.3.egg/pkg_resources.py", line 2014, in load
entry = __import__(self.module_name, globals(),globals(), ['__name__'])
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/__init__.py", line 43, in <module>
from .config.loader import Config
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/config/__init__.py", line 16, in <module>
from .application import *
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/config/application.py", line 31, in <module>
from IPython.config.configurable import SingletonConfigurable
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/config/configurable.py", line 26, in <module>
from .loader import Config
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/config/loader.py", line 27, in <module>
from IPython.utils.path import filefind, get_ipython_dir
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/utils/path.py", line 25, in <module>
from IPython.utils.process import system
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/utils/process.py", line 27, in <module>
from ._process_posix import _find_cmd, system, getoutput, arg_split
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/utils/_process_posix.py", line 22, in <module>
from IPython.external import pexpect
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/IPython/external/pexpect/__init__.py", line 2, in <module>
import pexpect
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/pexpect-2.4-py3.3.egg/pexpect.py", line 82
except ImportError, e:
^
SyntaxError: invalid syntax
After doing all that, I noted that my /Library/Frameworks/Python.framework/Versions/Current had been pointing to 2.7, and I guessed that that might be related to my problems and changed the symbolic link to point to 3.3, but iptest3 still fails with the error above.
Any other thoughts on what to do to fix this? It's clear that iptest is pretty important to doing anything else (like IPython Notebook) I want to do.
There is a py3-compatible fork of pexpect called pexpect-u (the u is for unicode, the main difference between the two). You need this to run the pexpect-based parts of IPython on Python 3.
Should be a simple
pip install pexpect-u
side note: pexpect-u is by IPython developer Thomas Kluyver, who did most of the heavy lifting bringing py3 compatibility to IPython.

Eclipse using multiple Python interpreters with execnet

I'm using the execnet package to allow communication between Python scripts interpreted by different Python interpreters.
The following code (test_execnet.py):
import execnet
for python_version in ('python', 'python3'):
try:
gw = execnet.makegateway("popen//python="+python_version)
ch = gw.remote_exec('channel.send(1/3)')
res = ch.receive()
print(python_version, ': ', res, sep ="")
except:
print('problems with ', python_version)
Runs perfectly in the command-line Terminal, showing the following output:
$ python3 test_execnet.py
python: 0
python3: 0.333333333333
However, if I try to run the same code from within the Eclipse IDE, I get the following error:
'import site' failed; use -v for traceback
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 4, in <module>
File "<string>", line 2, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/site-packages/execnet/gateway_base.py", line 8, in <module>
import sys, os, weakref
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/os.py", line 380, in <module>
from _abcoll import MutableMapping # Can't use collections (bootstrap)
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/python3.1/_abcoll.py", line 54
class Hashable(metaclass=ABCMeta):
^
SyntaxError: invalid syntax
problems with python
problems with python3
NOTE:
Eclipse Version: 3.6.0
PyDev Interpreter configured for the project: python3
"Preferences/Interpreter - Python"'s Python Interpreters:
python (/usr/bin/python)
python3 (/Library/Frameworks/Python.Framework/Versions/3.1/Resources/Python.app/Contents/MacOS/Python
EDIT:
I write a code to show the os.environ like this:
for python_version in ('python', 'python3'):
try:
import os
for item in os.environ:
print(item, '= ', os.environ[item])
except:
print('problems with ', python_version)
I got the following outputs:
eclipse_output.txt
terminal_output.txt
A FileMerge comparison of the files can be found at eclipse_output.txt vs. terminal_output.pdf.
Any hints?
Thanks
seems like pydev does site-customizations and particularly modifies things for interactive/console usage (judging from a very quick skim of http://github.com/aptana/Pydev/blob/master/plugins/org.python.pydev/pysrc/pydev_sitecustomize/sitecustomize.py ). This is not useful or fitting for execnet-mediated processes.
You could try to "del os.environ['PYTHONPATH']" before you invoke execnet.makegateway, or, to be more careful, just delete the sitecustomize part of it.
hth,
holger
'import site' failed; use -v for traceback
I have seen that when python was unable to find its landmark. Which that indicates there is a PYTHONHOME problem.
Check out http://docs.python.org/using/cmdline.html#envvar-PYTHONHOME maybe eclipse is screwing your environment up.
Edit:
Looked at your env dumps, looks like eclipse is definitely messing with PYTHONPATH, which will cause your child python processes to not work correctly.
Basically what you have going on here is eclipse starts a python v2 instance with a PYTHONPATH pointing to the python v2 directories. Then you spawn a python v3 process which tries to load its landmark from the python v2 directories...
You need to find a way to have eclipse not mess with the PYTHONPATH. I am not sure what eclipse is trying to do by doing that, but it is certainly no friend when you want to spawn new python processes.