Kevin McGinn · Feb 27, 2020 go to post

I added the import of the traceback lib as you suggested. Putting the traceback  statement after the execute or fetch caused an error stating that "last_type" does not exist which would I should see if no errors were found (as I understand it) . I changed the select to "select * ....." and that produced the error:

  File "getTables.py", line 45, in main
    tHdl.prepare(sql)
intersys.pythonbind3.cache_exception: file=intersys/pythonbind3.c line=3355 err=-1 message=cbind_prepare_gen_query()

an even more confusing error for which I have not found any info on the error condition.

I changed the the statement to "select count(*)...." that was a mistake. The python script never returned.

Kevin McGinn · Feb 27, 2020 go to post

"select 1" generates the same error:

    tHdl.prepare(sql)
intersys.pythonbind3.cache_exception: file=intersys/pythonbind3.c line=3355 err=-1 message=cbind_prepare_gen_query()

What is more perplexing is if I create a python script using an ODBC connection instead of pythonbind3,  the select does work. But I prefer not to use ODBC.

Kevin McGinn · Feb 27, 2020 go to post

Eduard Lebedyuk; thank-you for your help.

Unfortunately, switching to IRIS is not an option as we are preparing to support clients who are not prepared to upgrade to IRIS; at least not yet. I will, though, look at PythonGateway.

Again, thank-you for the help.

Kevin McGinn

Kevin McGinn · Mar 5, 2020 go to post

I am running this script on a Windows box. The Cos script file was written using notepad++. Because of this the file had windows line terminators.

The Fix: I updated the file replacing the Windows linefeeds with unix line feeds. The script functions perfectly now.

Thank-you for the help.

Kevin McGinn · Sep 3, 2021 go to post

I appreciate the feedback from the many respondents. To answer the question posed by the responses:

1) I did try zn "%SYS" this produces the response


ZN "%SYS"
^
<DIRECTORY> */cachesys/mgr/
<DIRECTORY> */cachesys/mgr/

which I take as it is not comprehending the command

2). The last command before this issue. I wanted to get db information using the $zu(49) which I then found has been deprecated. The $zu() method is new to me but there is documentation (apparently old) describing its utility to get information on a db.

3). As a database consultant we, unfortunately, only have a single sets of creds to access the server. Because of this I don't have the option to determine if the issue is isolated to my creds.

Kevin McGinn · Sep 8, 2021 go to post

After much discussion with Intersystems support the root cause of this error was/is that the cache.dat associated with the SYS namespace is missing. Review of system and cache logs does not give a clear indication as to how or when this occurred. Following the supprt guidance,  we have a near identical system ( identical cache version) so we can copy that cache.dat file. Per support, there will be some things to correct but that will get our system back up.

Kevin McGinn · Sep 22, 2021 go to post

The real issue is that the query and result processing functions without issue in an interactive term session. But when passed as a term script to a batch term session the  result processing is ignored. Because of this I know there are no real issues with the statement; just confused why there is an issue in the batch mode.

Kevin McGinn · Sep 22, 2021 go to post

SOLVED

The fix is to break the write statement into multiple 'send:' statements with the last send containing the trailing <CR>. So my write statement becomes:

send: WHILE rset.%Next() { set sub=$PIECE(rset.%Get("CurrentDevice"),"|",2) set devLen=$LENGTH(rset.%Get("CurrentDevice"),"|") set port=$PIECE(rset.%Get("CurrentDevice"),"|",3) set dev=rset.%Get("CurrentDevice") set IP=rset.%Get("ClientIPAddress") Write rset.%Get("jobNumber"),",", rset.%Get("Pid"),",",rset.%Get("UserName"),",",$CASE( devLen,1:"null",3:dev,4:"|"_sub_"|"_IP_"|"_port),",",rset.%Get("NameSpace"),",",rset.%Get("Routine"),",",rset.%Get("CommandsExecuted"),",",rset.%Get("GlobalReferences"),",",

send: rset.%Get("State"),!} <CR>

Kevin McGinn · Sep 24, 2021 go to post

Ok, so there isn't a problem with defining the static variable once as is proper design. based upon your response, I found the root cause of my issue. My static variable is a 600 char. string. This apparently exceeds the 'send:' buffer of the terminal script file. I broke the variable into 3 send: statements of 250, 250 and 100 chars in length the last send followed with a <CR>. The script functions without issue now.

Kevin McGinn · Sep 28, 2021 go to post

Per WRC. 2 possible fixes: 1). perform a install/repair, or 2). work with WRC to determine if the corruption is fixable.

Kevin McGinn · Oct 8, 2021 go to post

Intersystems continues to request a conclusion to this issue. I have already stated and included such. So this will be redundant. I worked with support, copied a cache.dat from another system of the same version to correct the issue.

Kevin McGinn · Oct 25, 2021 go to post

That makes sense. At any point I can manually reset the current size to a size less than or equal to the max size. But if I, at some point, reset the current size, cache will still attempt to allocate the space when this size I set is consumed. I believe this is correct. So, essentially I can manually intervene with the space allocation process but the automated space allocation process is still in place. 

Kevin McGinn · Nov 1, 2021 go to post

I appreciate the further edification on the management of the cache database; it will be useful going forward.

Kevin McGinn · Jan 26, 2022 go to post

I believe that I was able to answer my own question. In a csession I used the command "DO ^%GSIZE".  I specified the database path and the global of interest - in this case - STMONITS . The command generated the information I needed.

Kevin McGinn · Feb 1, 2022 go to post

I trying using the 'Do ^%RFIND' to determine the routines referencing the global. I specified 'STRELPERF' to search for and I stipulated to ignore case. Nothing was found. That doesn't make since since the global is 700+G in size. So I must be doing something incorrect. If they are application specific globals as noted I will again ask the client for details.

Kevin McGinn · Mar 1, 2022 go to post

Thank-you for your reply. I know cache is 64bit; I believe intersys.pythonbind3 is also 64bit though I am not entirely clear about how to validate that. The connection to the database works correctly. The following method calls with the connection work correctly:

db.run_class_method("%SYSTEM.INetInfo","LocalHostName",[])
db.run_class_method("%SYSTEM.Version","SystemMode",[])
db.run_class_method("%SYSTEM.Util","InstallDirectory",[])
db.run_class_method("%SYSTEM.Util","ManagerDirectory",[])
db.run_class_method("%SYSTEM.Util","NumberOfCPUs",[])

This is what makes the issue confusing. This intersys lib. appears to have the tools I need but perhaps I should revisit ODBC. I see the cache query builder is also based upon ODBC so perhaps that is the actual fix.

Kevin McGinn · Mar 3, 2022 go to post

I know this is an old post but I am having the same issue as detailed in this ticket using cache 2017.1.2. This is a client instance and upgrading to something current is not an option near term. I am rather new to accessing cache with Python so my error may be rather basic.

You stated that use can use the query "select DatabaseName, Directory....FROM SYS.Database_FreeSpace('*')". I have have trouble with the syntax apparently. I have the statement:

query.prepare("select * from SYS.Database_FreeSpace('*')")

but that fails with:

intersys.pythonbind3.cache_exception: file=intersys/pythonbind3.c line=3355 err=-1 message=cbind_prepare_gen_query()

I am obviously missing something.

Kevin McGinn · Mar 4, 2022 go to post

I have resolved this issue. I used:

execRes = qry.prepare_class("SYS.Database",'CompactLocalList')

to get basic information on each of the databases.  I then used object getters to get the other property values I needed. To get a object handle to each database I used:

_db = db.openid('SYS.Database', <database dir>,-1,-1)

Then

<prop value = _db.get(<property name>)

Kevin McGinn · Mar 5, 2022 go to post

Thank-you for the response. I now have found the class reference for 2017 where it is specified as a method as opposed to a classmethod.

Would you mind elaborating a bit on your statement "...wrap it in a class method". I see that in object script there is the $METHOD() which appears to be what I need but I am not find finding an equivalent python method.

Kevin McGinn · Mar 10, 2022 go to post

That is helpful but I still have open issues.

I am trying to determine why instanceConnections() instanceConnectionsMax() produce the correct answers in a Terminal session but return None in Python.

I also, if it is available would like to know where to find the values to use for the 'Distributed' column of that web page

Kevin McGinn · Mar 11, 2022 go to post

I am not sure what screen shot would be helpful.

I did find that the class ""%Monitor.System.License" contains the distributed license parameters that I need. What I am trying to figure out is the correct syntax to get a handle to the object. I tried:

   hdl = database.openid("%Monitor.System.License",'',-1,-1)

But this fails.

I also tried:

  hdl = database.run_class_method("%Monitor.System.License","%OpenId",[])

 But this object does not have the '%OpenId' method

If I can figure the correct syntax I can use hdl.get(xx) to get what I need for the distributed license attributes.

Kevin McGinn · Mar 11, 2022 go to post

This is a summary of the report that I am trying to create through a Python process:

For the values in the "local" column I am using the %SYSTEM.License class and setting the values as follows:

  Current License Units Used -     ->  LUConsumed

   Maximum License Units Used  --> LUMaxConsumed

   License Units Enforced               --> KeyEnforcedUnits

   License Units Authorized            --> KeyLicenseUnits

   Current Connections                   --> InstanceConnections

   Maximum Connections              --> InstanceConnectionsMax

The values appear to be match the Management Portal values. The instanceConnections and InstanceConnectionsMax in Python are Null so that is an open issue

For the values in the "distributed" column  are not completely clear. The first two values appear to be from the "%Monitor.SystemLicense" But this is my best guess. So for the distributed column I have:

      hdl = database.run_class_method("%Monitor.System.License","%New",[])

    Current License Units Used -     -->  hdl.get('CurrentUsedDist')

   Maximum License Units Used  -->hdl.get('MaxUsedDist')

   License Units Enforced               --> ?

   License Units Authorized            --> ?

   Current Connections                   --> ?

   Maximum Connections              --> ?

At this point I would like know how to get the missing distributed license values. Also, is the "%Monitor.System.License" the correct source for some of the distributed values?

Kevin McGinn · Mar 23, 2022 go to post

I resolved this issue. The intersys.pythonbind3 import on Windows references the dir "C:\Users\<user name>\AppData\Local\Programs\Python\Python37\Lib\site-packages\pythonbind3-1.0-py3.7-win-amd64.egg\intersys". I found that I can copy the contents of that dir to another windows server which allows the process to execute on a remote server even if cache is not installed on that remote server

Kevin McGinn · Mar 23, 2022 go to post

In talking to Intersystems in regards to this issue, the query that I would need to use is not defined as a proc. Unknown if that will be corrected in the future or not.

The prescribed solution was stated as:

"...So the solution requires writing your own method in ObjectScript that uses %ResultSet to run the query. Your method then loops through the results, and creates something that can be returned. You call your method from Python" [ joel.solon@intersystems.com ]

So I am closing this issue out. I may pursue that approach at a later date.

Kevin McGinn · Apr 20, 2022 go to post

I was able to resolve this issue by use the %Library.ResultSet' object '%New() method (python)

hdl = self.db.run_class_method('%Library.ResultSet',"%Library.ResultSet',%New",[])

The setting the class name and query to be executed:

        hdl.set("ClassName","%SYSTEM.License")
        hdl.set("QueryName","Summary")

This is then executed:

hdl.run_obj_method("%Execute",[])

The results are process in a while loop while the value of:

status = None

conStat=True


while conStat:
                lStat = hdl.run_obj_method("%Next",[status])

               if lStat:

                       < process results>

              conStat = lStat

There may be more elegent refinements to this python solution but this does accurate extract and return the license usage summary data