5

I encountered a similar problem as dicussed in here:

Firebird embedded installation issue: library could not be determined

I'm running a python(3.5.2) script via ubuntu (16.04.4 LTS) which is connected to a firebird database. For installing firebird I followed the instructions provided in here:

https://firebirdsql.org/manual/ubusetup.html

Now, when I run the python code the following error is displayed:

Soft limit starts as  :-1
Soft limit changed to :1024
Traceback (most recent call last):
  File "clustering_setup.py", line 30, in <module>
    graph, posi_knoten, kanten_bewertung, auslassliste = build_netzwerk.create_graph()
  File "/home/ubuntu/Documents/Code/build_netzwerk.py", line 113, in create_graph
    datenbank_custom.start(config.idbf_file)
  File "/home/ubuntu/Documents/Code/datenbank_custom.py", line 19, in start
    con = fdb.connect(database=idbf_file, user='sysdba', password='pass')
  File "/home/ubuntu/.local/lib/python3.5/site-packages/fdb/fbcore.py", line 682, in connect
    load_api(fb_library_name)
  File "/home/ubuntu/.local/lib/python3.5/site-packages/fdb/fbcore.py", line 181, in load_api
    setattr(sys.modules[__name__],'api',fbclient_API(fb_library_name))
  File "/home/ubuntu/.local/lib/python3.5/site-packages/fdb/ibase.py", line 1398, in __init__
    raise Exception("The location of Firebird Client Library could not be determined.")
Exception: The location of Firebird Client Library could not be determined.

if I examine where the files are located this is what is shown to me:

ubuntu@ubuntu:~$ dpkg -L firebird2.5-classic-common
/.
/usr
/usr/share
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/firebird2.5-classic-common
/usr/share/doc
/usr/bin
/usr/bin/qli
/usr/bin/nbackup
/usr/bin/fbstat
/usr/bin/fbtracemgr
/usr/bin/gdef
/usr/bin/gsec
/usr/bin/isql-fb
/usr/bin/gpre
/usr/bin/gbak
/usr/bin/fbsvcmgr
/usr/bin/gfix
/usr/lib
/usr/lib/firebird
/usr/lib/firebird/2.5
/usr/lib/firebird/2.5/UDF
/usr/lib/firebird/2.5/UDF/ib_udf.so
/usr/lib/firebird/2.5/UDF/fbudf.so
/usr/sbin
/usr/sbin/fb_lock_print
/usr/share/doc/firebird2.5-classic-common

output of locate libfbclient:

/usr/lib/x86_64-linux-gnu/libfbclient.so.2
/usr/lib/x86_64-linux-gnu/libfbclient.so.2.5.4
/usr/share/doc/libfbclient2
/var/cache/apt/archives/libfbclient2_2.5.4.26856.ds4-1build1_amd64.deb
/var/lib/dpkg/info/libfbclient2:amd64.list
/var/lib/dpkg/info/libfbclient2:amd64.md5sums
/var/lib/dpkg/info/libfbclient2:amd64.postinst
/var/lib/dpkg/info/libfbclient2:amd64.postrm
/var/lib/dpkg/info/libfbclient2:amd64.preinst
/var/lib/dpkg/info/libfbclient2:amd64.shlibs
/var/lib/dpkg/info/libfbclient2:amd64.symbols

applying cat /etc/ld.so.conf.d/* leads to:

ubuntu@ubuntu:~/Documents/Code$ cat /etc/ld.so.conf.d/*
/usr/lib/x86_64-linux-gnu/libfakeroot
# Multiarch support
/lib/i386-linux-gnu
/usr/lib/i386-linux-gnu
/lib/i686-linux-gnu
/usr/lib/i686-linux-gnu
# libc default configuration
/usr/local/lib
# Multiarch support
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/mesa-egl
/usr/lib/x86_64-linux-gnu/mesa   

result for ldconfig -p | grep libfbclient

libfbclient.so.2 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libfbclien.so.2

thats the script im running!

from datetime import datetime
import funcs
import build_netzwerk
from scipy.optimize import minimize_scalar
import matplotlib.pyplot as plot
import funcs_nachbearb
import config

start = datetime.now()

# abstandsgewichteten Graphen berechnen
graph, posi_knoten, kanten_bewertung, auslassliste = build_netzwerk.create_graph()

# zurückgegebene Werte bestimmen
if config.clusteringtyp == 'sohlhoehe':
    kanten_durchfluss = kanten_bewertung[1].copy()
    kanten_bewertung = kanten_bewertung[0].copy()
elif config.clusteringtyp == 'durchfluss':
    kanten_durchfluss = kanten_bewertung.copy()
else:
    kanten_durchfluss = kanten_bewertung.copy()
    kanten_bewertung = None

# minimalen Optimierungsfaktor bestimmen
print(datetime.now() - start)
erg_min = minimize_scalar(funcs.optimiere_cluster, args=(graph, kanten_bewertung, auslassliste, 'min'),
                          bounds=(0, 10), method='bounded')
# print(erg_min)

# maximalen Optimierungsfaktor bestimmen
print(datetime.now() - start)
erg_max = minimize_scalar(funcs.optimiere_cluster, args=(graph, kanten_bewertung, auslassliste, 'max'),
                          bounds=(erg_min.x, 10), method='bounded')
# print(erg_max)

# besten Optimierungsfaktor bestimmen
print(datetime.now() - start)
clustersammlung = funcs.bruteforce_optim(erg_min.x, erg_max.x, graph, kanten_bewertung, auslassliste,
                                         kanten_durchfluss)

print(datetime.now() - start)

# Clusternummerierung soll von 0 bis Anzahl gewünschter Cluster laufen
funcs_nachbearb.transform_clusternummern(clustersammlung)

# Bewertung der Cluster berechnen
print(funcs_nachbearb.cluster_bewertung(clustersammlung, graph, kanten_durchfluss))

# Clusterhierarchie berechnen
print(funcs_nachbearb.cluster_hierarchie(clustersammlung, graph))

# Schächte der Messstationen ausgeben
ms = ""
for key in clustersammlung.keys():
    ms = ms + clustersammlung[key].endpoint + ", "
ms.rstrip(", ")
print("Messstationen: " + ms)

# Einflussgebiete auf die Messstationen ausgeben
print("Einflussgebiete:")
for key in clustersammlung.keys():
    print("Einflussgebiet von Cluster " + str(key) + ": " + ", ".join(clustersammlung[key].nodes))


print(datetime.now() - start)

# entstehenden Grpahen mit Clustern zeichnen
funcs.draw_clustered_graph(graph, posi_knoten, clustersammlung)
plot.show()


print(datetime.now() - start)

datenbank_custom:

import fdb

con = None


def start(idbf_file):
    """
    Verbindung mit idbf-Datenbank aufbauen

    :param idbf_file: (str) Dateipfad zur Datenbank
    """

    global con
    con = fdb.connect(database=idbf_file, user='sysdba', password='pass')


def stop():
    """
    Verbindung mit idbf-Datenbank trennen
    """

    global con
    con.close()


def read_from_db_single(sqlstatement):
    """
    Allgemeine Funktion um einen einzelnen Wert aus dem IDBF-File auszulesen

    :param sqlstatement: (str) SQL-Abfrage zum auslesen eines Wertes

    :return results: abgefragter Wert
    """

    curs = con.cursor()  # Use a client side cursor so you can access curs.rowcount
    curs.execute(sqlstatement)
    results = curs.fetchone()

    if results:
        results = results[0]

    del curs
    return results


def read_from_db(sqlstatement):
    """
    Allgemeine Funktion um Daten aus dem IDBF-File auszulesen

    :param sqlstatement: (str) SQL-Abfrage an Datenbank

    :return results: Rückgabe der Abfrage
    """

    curs = con.cursor()  # Use a client side cursor so you can access curs.rowcount
    curs.execute(sqlstatement)
    results = curs.fetchall()

    del curs
    return results


def read_network(infotyp=None):
    """
    Gibt die Knoten und die Kanten für das Kanalnetzmodel zurück.
    Alle Schachttypen sind Knoten, alle Haltungen, Sonderbauwerke, ... sind Kanten

    :param infotyp: (str) String zur Erweiterung der SELECT-Werte an die Kanten

    :return results_knoten: (list(tuple(str, float, float))) Listen der Knoteninformationen
    :return results_kanten: (list(tuple(str, float, float, [...]))) Listen der Kanteninformationen;
                            list(tuple(name, schachtoben, -unten, infotyp[i])
    :return results_sonderkanten: (list(tuple(str, float, float))) Listen der Sonderkanteninformationen
    """

    erweiterung = ''
    if infotyp is not None:
        erweiterung = infotyp

    knoten = "SELECT name,XKOORDINATE,YKOORDINATE from SCHACHT UNION " + \
             "SELECT name,XKOORDINATE,YKOORDINATE from SPEICHERSCHACHT UNION " + \
             "SELECT name,XKOORDINATE,YKOORDINATE from AUSLASS;"

    kanten = "SELECT name,schachtoben,schachtunten" + erweiterung + " from ROHR UNION " + \
             "SELECT name,schachtoben,schachtunten" + erweiterung + " from HREGLER UNION " + \
             "SELECT name,schachtoben,schachtunten" + erweiterung + " from QREGLER;"

    sonderkanten = "SELECT name,schachtoben,schachtunten from DROSSEL UNION " + \
                   "SELECT name,schachtoben,schachtunten from GRUNDSEITENAUSLASS UNION " + \
                   "SELECT name,schachtoben,schachtunten from PUMPE UNION " + \
                   "SELECT name,schachtoben,schachtunten from SCHIEBER UNION " + \
                   "SELECT name,schachtoben,schachtunten from WEHR;"

    curs = con.cursor()  # Use a client side cursor so you can access curs.rowcount

    curs.execute(knoten)
    results_knoten = list(curs.fetchall())

    curs.execute(kanten)
    results_kanten = list(curs.fetchall())

    curs.execute(sonderkanten)
    results_sonderkanten = list(curs.fetchall())

    del curs

    return results_knoten, results_kanten, results_sonderkanten

I'd appreciate your advise on that, because I have absolutely no clue how to fix that particular issue!

Olli
  • 295
  • 4
  • 14
  • What is the output of `locate libfbclient` (you may need to do an `sudo updatedb` first if you installed Firebird recently)? – Mark Rotteveel Mar 19 '18 at 10:52
  • Did you install package `libfbclient2`? – Mark Rotteveel Mar 19 '18 at 11:02
  • @MarkRotteveel, I install _libfbclient2_ already, but still the error is displayed. – Olli Mar 19 '18 at 11:28
  • Could you edit the question and add it there? That makes it more readable than in the comments. I'll see if I can reproduce this and provide a solution. – Mark Rotteveel Mar 19 '18 at 11:32
  • @Mark sure, i'll do that ! – Olli Mar 19 '18 at 11:33
  • I'm afraid I can't reproduce it (Ubuntu 17.10, libfbclient2 3.0.2, python 3.6 and fdb 1.8). I'll try to find the time to install a clean 16.04 VM and see if I can reproduce it that way – Mark Rotteveel Mar 19 '18 at 12:42
  • What is the output of `python3 -c 'import struct;print( 8 * struct.calcsize("P"))'`? (if you are using another python executable for running your application, then substitute that). – Mark Rotteveel Mar 19 '18 at 14:37
  • @Mark, my output is 64 for that case – Olli Mar 19 '18 at 14:54
  • Ok, then the only other idea I had to explain your problem is also out (32 bit python can't use a 64 bit libfbclient). – Mark Rotteveel Mar 19 '18 at 14:56
  • In any case, did you try `sudo ldconfig` as I suggested in my answer? – Mark Rotteveel Mar 19 '18 at 15:18
  • i tried that, but the error is still present – Olli Mar 19 '18 at 15:43
  • What is the output for `ldconfig -p | grep libfbclient`? – Mark Rotteveel Mar 19 '18 at 16:00
  • @Mark, I added the output for your requested to the question. what do you conclude from that? – Olli Mar 19 '18 at 19:17
  • I assume the libfbclien.so.2 in there is a typo, otherwise it would seem the symlink is wrong? Could you explicitly add the `fdb.connect` string of your application to the question, the only other thing I can think of is that you explicitly specify the property `fb_library_name`. Or try explicitly setting `fb_library_name='/usr/lib/x86_64-linux-gnu/libfbclient.so.2'` in the connect method. – Mark Rotteveel Mar 19 '18 at 19:30
  • Hey @Mark, im afraid I don't exactly get what you are asking for. I should just apply "fb_library_name='/usr/lib/x86_64-linux-gnu/libfbclient.so.2" ? – Olli Mar 20 '18 at 09:20
  • Could you show the source of your application that connects to Firebird? – Mark Rotteveel Mar 20 '18 at 10:48
  • hi @Mark, sorry for my late reply. i added the running script to the current description up there. would u also need to see all the importet scripts additionally? thanks a lot for your support until here!! – Olli Mar 24 '18 at 12:50
  • The code in `datenbank_custom.py` is probably the most relevant. – Mark Rotteveel Mar 24 '18 at 12:52
  • have attached that one as well – Olli Mar 24 '18 at 14:21

1 Answers1

4

I installed Ubuntu 16.04.4 as a fresh VM, and only did an sudo apt-get update/sudo apt-get upgrade

And then did the following:

sudo apt install python3-pip
sudo apt install libfbclient2
mkdir fdb-experiment
cd fdb-experiment
pip3 install fdb
nano connect.py

With connect.py:

import fdb

# 172.26.69.161 is my Windows machine with Firebird
con = fdb.connect(dsn='172.26.69.161:d:/data/db/testdatabase.fdb', user='sysdba', password='masterkey')
cur = con.cursor()
cur.execute("select * from rdb$database")
print(cur.fetchall())

Then:

python3 connect.py

Output:

[(None, 225, None, 'ISO8859_1                      ')]

I did have to restart my VM in between because of some networking problems to the Windows host OS (which is running the Firebird server I used). I can only reproduce your problem if I perform sudo apt remove libfbclient2.

In other words, I can't reproduce your problem. The only thing I can think of is that maybe you're using an older version of fdb (I'm using 1.8) which locates the client library in a different way (but as your stacktrace has the same line numbers I see if I remove libfbclient2, that is likely not the case).

You might want to try if running sudo ldconfig fixes the problem, this will rebuild the cache of shared libraries. If that doesn't work, then check if cat /etc/ld.so.conf.d/* lists /usr/lib/x86_64-linux-gnu (if it doesn't, then I'm not entirely sure what would be the correct course of action to fix that).

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197