W Pythonie utworzyłem bibliotekę, która zawiera funkcje dostępu do bazy danych. Jest to biblioteka otoki wokół bazy danych aplikacji innych firm, napisana z powodu faktu, że aplikacja innej firmy nie oferuje przyzwoitego interfejsu API. Teraz początkowo pozwalałem każdej funkcji otwierać połączenie z bazą danych na czas trwania wywołania funkcji, co było OK, dopóki moja logika programu nie używała zagnieżdżonych wywołań funkcji, w których wówczas wywoływałabym określoną funkcję kilka tysięcy razy. To nie było zbyt wydajne. Profilowanie tego pokazało, że narzut był w konfiguracji połączenia z bazą danych - raz na wywołanie funkcji. Dlatego przeniosłem otwarte połączenie z funkcji do samego modułu, aby połączenie z bazą danych zostało otwarte podczas importowania modułu biblioteki. To dało mi akceptowalną wydajność.
Teraz mam dwa pytania dotyczące tego. Po pierwsze, czy muszę się martwić, że nie zamykam już wyraźnie połączenia z bazą danych i jak mogę to zrobić w tej konfiguracji? Po drugie, czy to, co zrobiłem, nie jest zbliżone do obszaru dobrych praktyk i jak mógłbym do tego podejść?
openConn
funkcję i spraw, aby użytkownik przekazał ją do każdej wywoływanej funkcji, w ten sposób można zawęzić zakres połączenia wwith
instrukcji lub czymkolwiek innymOdpowiedzi:
To zależy od używanej biblioteki. Niektóre z nich mogą same zamykać połączenie (Uwaga: sprawdziłem wbudowaną bibliotekę sqlite3, ale tak się nie dzieje). Python wywoła destruktor, gdy obiekt wykracza poza zasięg, a biblioteki te mogą implementować destruktor, który z wdziękiem zamyka połączenia.
Jednak może tak nie być! Poleciłbym, jak inni mają w komentarzach, zawinięcie go w obiekt.
Spowoduje to utworzenie instancji połączenia z bazą danych na początku i zamknięcie go, gdy miejsce, w którym utworzono instancję, wykracza poza zakres. Uwaga: Jeśli utworzysz instancję tego obiektu na poziomie modułu, będzie on trwał dla całej aplikacji. Jeśli nie jest to zamierzone, sugerowałbym oddzielenie funkcji bazy danych od funkcji innych niż baza danych.
Na szczęście Python ustandaryzował interfejs API bazy danych , więc będzie on działał ze wszystkimi zgodnymi bazami danych :)
źródło
self
wdef query(self,
?db.query('SELECT ...', var)
i narzekałem na potrzebę trzeciego argumentu.MyDB
najpierw utworzyć instancję obiektu:db = MyDB(); db.query('select...', var)
ResourceWarning: unclosed <socket.socket...
podczas obsługi połączeń z bazą danych należy się martwić o dwie rzeczy:
zapobiegać wielu wystąpieniom połączeń, pozwalanie każdej funkcji na otwarcie połączenia z bazą danych jest uważane za złą praktykę, biorąc pod uwagę ograniczoną liczbę sesji bazy danych, których zabraknie; przynajmniej twoje rozwiązanie nie skaluje się, zamiast tego używasz wzorca singletonu, twoja klasa byłaby tworzona tylko raz, aby uzyskać więcej informacji na temat tego wzorca zobacz link
zamykając połączenie przy wyjściu z aplikacji, powiedzmy, że nie, i że masz co najmniej tuzin uruchomionych aplikacji, które robią to samo, na początku wszystko pójdzie dobrze, ale zabraknie sesji bazy danych i jedyna poprawka byłoby zrestartowanie serwera bazy danych, co nie jest dobre dla aplikacji na żywo, dlatego w miarę możliwości używaj tego samego połączenia.
aby zestalić wszystkie te pojęcia, zobacz następujący przykład, który otacza psycopg2
źródło
if Database._instance is None: NameError: name 'Database' is not defined
. Nie rozumiem, co toDatabase
jest i jak mogę to naprawić.Postgres.query(Postgres(), some_sql_query)
wwhile
pętli, to nadal otwierać i zamykać połączenie w każdej iteracji, czy pozostawić go otworzyć przez cały czas wwhile
pętli aż do zjazdu z programu?query()
funkcji, ale wydaje się, że jest problem z moim kodem, kiedy uruchamiam moją aplikację w trybie „równoległym”.Interesujące byłoby zaoferowanie możliwości zarządzania kontekstem dla twoich obiektów. Oznacza to, że możesz napisać taki kod:
Zapewni to wygodny sposób na automatyczne zamknięcie połączenia z bazą danych poprzez wywołanie klasy za pomocą instrukcji with:
źródło
Długo się nad tym zastanawiałam. Do dnia znalazłem sposób. nie wiem, to najlepszy sposób. tworzysz plik o nazwie: conn.py i zapisujesz go w folderze /usr/local/lib/python3.5/site-packages/conn/. Używam freebsd i to jest ścieżka do mojego folderu pakietów witryn. w moim conn.py: conn = "dbname = omnivore user = postgres password = 12345678"
`` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` a w skrypcie chcę wywołać połączenie, piszę:
import psycopg2 import psycopg2.extras import psycopg2.extensions
from conn import conn try: conn = psycopg2.connect (conn.conn) z wyjątkiem: page = "Nie można uzyskać dostępu do bazy danych"
cur = conn.cursor ()
i bla bla ...
mam nadzieję, że to przydatne
źródło