Łączenie z bazą danych za pomocą SQLAlchemy
Utwórz silnik SQLAlchemy dla SQLite i PostgreSQL, a następnie przekaż go do pd.read_sql, aby wczytać tabelę do DataFrame.
Łączenie z bazą danych za pomocą SQLAlchemy to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Dlaczego łączyć Pandas z bazami danych?
Większość danych produkcyjnych znajduje się w relacyjnych bazach danych — PostgreSQL, MySQL, SQLite lub SQL Server — a nie w plikach CSV. Bezpośrednie połączenie Pandas z bazą danych umożliwia pobieranie danych do obiektu DataFrame bez wcześniejszego eksportowania ich do CSV, zapisywanie oczyszczonych obiektów DataFrame z powrotem do tabel oraz łączenie możliwości analitycznych języka Python z funkcjami indeksowania i łączenia oferowanymi przez bazę danych. Pomostem między Pandas a bazami danych jest SQLAlchemy, standardowa biblioteka abstrakcji baz danych w języku Python.
Instalowanie SQLAlchemy
SQLAlchemy to zestaw narzędzi SQL i ORM dla języka Python. Do integracji z Pandas potrzebna jest tylko warstwa Core — nie ORM. Instalację należy wykonać za pomocą pip install sqlalchemy. Potrzebny jest również sterownik konkretnej bazy danych: psycopg2 dla PostgreSQL, pymysql dla MySQL lub sqlite3 (wbudowany w Pythonie) dla SQLite. SQLAlchemy pełni funkcję warstwy abstrakcji: ten sam kod Pandas działa z każdą obsługiwaną bazą danych, jeśli zmieni się tylko ciąg połączenia.
# Install dependencies
# pip install sqlalchemy psycopg2-binary # for PostgreSQL
# pip install sqlalchemy pymysql # for MySQL
# sqlite3 is built into Python
import sqlalchemy as sa
import pandas as pd
print('SQLAlchemy version:', sa.__version__)Tworzenie silnika połączenia
Pierwszym krokiem jest utworzenie silnika SQLAlchemy za pomocą adresu URL połączenia, który zawiera typ bazy danych, dane uwierzytelniające, host, port i nazwę bazy danych. Silnik jest fabryką połączeń z bazą danych — nie otwiera połączenia, dopóki nie będzie ono rzeczywiście potrzebne. Należy przekazać silnik do funkcji Pandas pd.read_sql() i df.to_sql(). Nie należy nigdy wpisywać danych uwierzytelniających bezpośrednio w kodzie; należy odczytywać je ze zmiennych środowiskowych lub menedżera sekretów.
import sqlalchemy as sa
import os
# SQLite (file-based, no server needed)
sqlite_engine = sa.create_engine('sqlite:///mydata.db')
# PostgreSQL
# pg_url = 'postgresql://user:pass@localhost:5432/mydb'
# pg_engine = sa.create_engine(pg_url)
# From environment variable (safer)
# pg_engine = sa.create_engine(os.environ['DATABASE_URL'])
print(sqlite_engine)
print(type(sqlite_engine))Odczytywanie tabeli za pomocą pd.read_sql_table()
pd.read_sql_table('table_name', con=engine) odczytuje całą tabelę bazy danych do obiektu DataFrame. Automatycznie rozpoznaje typy danych kolumn na podstawie schematu bazy danych — liczby całkowite pozostają liczbami całkowitymi, znaczniki czasu stają się obiektami datetime itd. Jest to dokładniejsze niż rozpoznawanie typów w plikach CSV. Kolumny można również ograniczyć za pomocą argumentu columns, a wiersze filtrować za pomocą schema w przypadku schematów baz danych innych niż domyślny. W przypadku bardzo dużych tabel należy zachować ostrożność: cała zawartość zostanie załadowana do pamięci RAM.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Read a full table
df = pd.read_sql_table('orders', con=engine)
print(df.shape)
print(df.dtypes)
print(df.head())Wykonywanie zapytań za pomocą pd.read_sql_query()
pd.read_sql_query('SELECT ...', con=engine) wykonuje dowolne zapytanie SQL typu SELECT i zwraca wyniki jako obiekt DataFrame. To najbardziej elastyczne podejście: można filtrować, łączyć i agregować dane w SQL przed załadowaniem ich do Pandas, pobierając tylko potrzebne wiersze i kolumny. Zapytanie należy zapisać jako zwykły ciąg znaków języka Python. Nie należy nigdy łączyć danych wprowadzonych przez użytkownika z zapytaniami — w celu zapobiegania atakom SQL injection należy używać zapytań parametryzowanych.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
query = '''
SELECT customer_id, SUM(amount) AS total_spent,
COUNT(*) AS num_orders
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 100
'''
top_customers = pd.read_sql_query(query, con=engine)
print(top_customers.head())Zapytania parametryzowane dla bezpieczeństwa
Nie należy nigdy budować zapytań SQL przez konkatenację ciągów znaków z wartościami podanymi przez użytkownika — otwiera to drogę do luk umożliwiających ataki SQL injection. Zamiast tego należy używać zapytań parametryzowanych: parametry należy przekazywać jako słownik z nazwanymi symbolami zastępczymi. SQLAlchemy obsługuje ich poprawne maskowanie. Składnia symboli zastępczych to :name w zapytaniach tekstowych SQLAlchemy lub %(name)s w zapytaniach w stylu psycopg2. Parametryzacji należy używać zawsze, nawet w skryptach wewnętrznych, aby wyrobić sobie dobre nawyki.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Safe: parameterised query
params = {'status': 'completed', 'min_amount': 500.0}
query = sa.text(
'SELECT * FROM orders WHERE status = :status AND amount > :min_amount'
)
with engine.connect() as conn:
df = pd.read_sql_query(query, con=conn, params=params)
print(f'Loaded {len(df)} rows')Obsługa dużych wyników zapytań partiami
W przypadku dużych wyników zapytań należy użyć parametru chunksize w funkcji pd.read_sql_query(), aby otrzymać iterator obiektów DataFrame zamiast ładować wszystko naraz. Działa to podobnie jak pd.read_csv(chunksize=...), ale pobiera wiersze z bazy danych partiami. W połączeniu ze wzorcem akumulatora narastającego umożliwia agregowanie wyników zapytań zwracających miliony wierszy bez wyczerpywania pamięci RAM.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('postgresql://user:pass@host/db')
total = 0.0
count = 0
for chunk in pd.read_sql_query(
'SELECT amount FROM orders',
con=engine,
chunksize=50000
):
total += chunk['amount'].sum()
count += len(chunk)
print(f'Mean amount: {total/count:.2f}')Menedżery kontekstu połączeń
Połączenia z bazą danych należy zawsze otwierać wewnątrz menedżera kontekstu (with engine.connect() as conn:), aby mieć pewność, że połączenie zostanie prawidłowo zamknięte nawet w przypadku wystąpienia wyjątku. Brak zamykania połączeń prowadzi w środowisku produkcyjnym do wyczerpania puli połączeń, przez co nowe zapytania mogą zawisnąć w oczekiwaniu na wolne miejsce. Pula połączeń SQLAlchemy zarządza stałą liczbą połączeń i automatycznie wykorzystuje je ponownie, gdy używane są menedżery kontekstu.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Using context manager — connection always closed properly
with engine.connect() as conn:
df = pd.read_sql_query(
'SELECT * FROM products WHERE category = "Electronics"',
con=conn
)
print(f'Products loaded: {len(df)}')
# Connection is automatically returned to the pool hereSprawdzanie schematu bazy danych
Przed napisaniem zapytań trzeba wiedzieć, jakie tabele i kolumny istnieją. Funkcja Inspector biblioteki SQLAlchemy umożliwia odczytanie schematu bazy danych bez pisania surowego kodu SQL. inspector.get_table_names() wyświetla listę wszystkich tabel, a inspector.get_columns('table') zwraca nazwy i typy kolumn. Jest to przydatne podczas pracy z nieznanymi bazami danych i czytelniejsze niż ręczne uruchamianie poleceń PRAGMA table_info() lub \d tablename.
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
inspector = sa.inspect(engine)
# List all tables
tables = inspector.get_table_names()
print('Tables:', tables)
# Get columns for the 'orders' table
for col in inspector.get_columns('orders'):
print(f' {col["name"]}: {col["type"]}')Zamykanie silników i dobre praktyki
W długo działających skryptach lub aplikacjach internetowych po zakończeniu pracy należy wywołać engine.dispose(), aby zamknąć wszystkie połączenia w puli. W przypadku krótkich skryptów sprzątaniem zajmuje się moduł garbage collectora języka Python. Dobre praktyki dotyczące połączeń z bazą danych w potokach danych: utworzyć silnik raz na początku skryptu i używać go ponownie, korzystać z domyślnych ustawień puli połączeń (pool_size=5) oraz włączyć pool_pre_ping=True, aby automatycznie ponownie nawiązywać połączenie, jeśli serwer bazy danych uruchomi się ponownie między zapytaniami.
import sqlalchemy as sa
# Production-grade engine creation
engine = sa.create_engine(
'postgresql://user:pass@host:5432/mydb',
pool_size=5, # max 5 persistent connections
max_overflow=10, # allow 10 temporary extra connections
pool_pre_ping=True, # verify connection before use
connect_args={'connect_timeout': 10}
)
# ... run all your queries ...
# At the end of the application/script
engine.dispose()
print('Engine disposed')Porównanie szybkości read_sql i read_csv
W przypadku danych znajdujących się już w bazie danych z odpowiednimi indeksami pd.read_sql_query z filtrowanym zapytaniem jest często szybsze niż eksportowanie danych do CSV i jego odczyt. Serwer bazy danych stosuje filtry przed wysłaniem danych, ograniczając transfer sieciowy i narzut związany z analizowaniem danych. W przypadku bardzo szerokich tabel baza danych może również zwrócić tylko potrzebne kolumny. Jednak odczyt z oddalonej bazy danych przez wolną sieć może być wolniejszy niż odczyt lokalnego pliku Parquet — należy zawsze zmierzyć wydajność obu rozwiązań w konkretnym środowisku.
import pandas as pd
import sqlalchemy as sa
import time
engine = sa.create_engine('sqlite:///data.db')
# Database read with server-side filter
start = time.time()
df_sql = pd.read_sql_query(
'SELECT * FROM transactions WHERE amount > 100 AND year = 2024',
con=engine
)
print(f'SQL read: {time.time()-start:.3f}s, {len(df_sql):,} rows')Szybkie sprawdzenie
Proszę sprawdzić swoją znajomość zagadnień analizy danych z tej lekcji.
Podsumowanie lekcji
W tej lekcji nauczyli się Państwo, że: sa.create_engine() tworzy wielokrotnego użytku fabrykę połączeń na podstawie ciągu URL, pd.read_sql_query() wykonuje dowolne zapytania SQL i zwraca obiekt DataFrame, a zapytania parametryzowane z sa.text() i params zapobiegają lukom umożliwiającym ataki SQL injection. W następnej części przyjrzymy się wykonywaniu bardziej złożonych zapytań SQL z poziomu Pandas oraz łączeniu SQL z logiką języka Python.
Ucz się Python dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 30
- Lekcje
- 120
Często zadawane pytania
Czy lekcja „Łączenie z bazą danych za pomocą SQLAlchemy” jest bezpłatna?
Tak — pełny tekst „Łączenie z bazą danych za pomocą SQLAlchemy” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Łączenie z bazą danych za pomocą SQLAlchemy”?
Utwórz silnik SQLAlchemy dla SQLite i PostgreSQL, a następnie przekaż go do pd.read_sql, aby wczytać tabelę do DataFrame. Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?
Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Łączenie z bazą danych za pomocą SQLAlchemy”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?
Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Łączenie z bazą danych za pomocą SQLAlchemy
- Wykonywanie zapytań SQL z Pandas
- Zapisywanie obiektów DataFrame w tabelach bazy danych
- Pandas a SQL: wybór odpowiedniego narzędzia