Gần đến tối thứ Sáu, và đội tại H+S đã sẵn sàng để nấu ăn. Giảm bớt ánh sáng và chìm vào một thứ gì đó thoải mái hơn khi chúng tôi đưa bạn đến với hương vị xa hoa 100% hữu cơ này. Thực đơn tối nay? . PyMySQL
PyMySQL là một thư viện nhẹ hoàn hảo cho các tập lệnh đơn giản. Nếu bạn đang tìm cách kết nối với cơ sở dữ liệu MySQL và thực hiện một số truy vấn đơn giản, thì không cần tìm đâu xa. PyMySQL sẽ không cung cấp cho chúng tôi các loại chuông và còi đi kèm với các thư viện như SQLAlchemy, điều này tốt nếu chúng tôi đang tìm cách xây dựng một điểm cuối nhanh. Một trường hợp sử dụng tuyệt vời cho PyMySQL là để sử dụng trong AWS Lambda [hoặc các chức năng serverless khác]. Chúng ta sẽ làm điều đó, nhưng bây giờ, hãy nấu món gì đó ngon
Làm nóng bếp
Bật ga và chuẩn bị bàn ăn với bộ sưu tập đĩa yêu thích của bạn. Đúng rồi; . Bạn biết nó sẽ đến. mỗi khi bạn muốn làm điều gì đó thật thú vị, chúng ta cần bắt tay vào công việc quản lý kết nối và những thứ tương tự. Để giảm bớt khó khăn, tôi sẽ chia sẻ với bạn một phương pháp ưa thích để xử lý các kết nối mở bằng PyMySQL
Trước tiên, chúng ta cần tạo một tệp cấu hình. Không giống như SQLAlchemy, PyMySQL không hỗ trợ các chuỗi URI cơ sở dữ liệu ngay lập tức. Do đó, chúng ta cần đặt các biến cho từng phần của kết nối cơ sở dữ liệu như tên người dùng, mật khẩu, v.v.
"""Config values."""
from os import environ, path
from dotenv import load_dotenv
basedir = path.abspath[path.dirname[__file__]]
load_dotenv[path.join[basedir, '.env']]
# Database config
db_user = environ.get['DATABASE_USERNAME']
db_password = environ.get['DATABASE_PASSWORD']
db_host = environ.get['DATABASE_HOST']
db_port = environ.get['DATABASE_PORT']
db_name = environ.get['DATABASE_NAME']
cấu hình. pyChúng tôi đang lấy các giá trị cho từng giá trị này từ một. tập tin env. một thực tế tôi rất khuyến khích cho mục đích bảo mật
thịt và khoai tây
Tôi sẽ chứa tất cả logic cơ sở dữ liệu của ứng dụng trong một lớp có tên là Cơ sở dữ liệu để chứa tất cả các biến và hàm liên quan đến kết nối cơ sở dữ liệu
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
Xây dựng lớp cơ sở dữ liệuViệc khởi tạo lớp này sẽ lưu các biến kết nối cơ sở dữ liệu của chúng ta vào thể hiện của lớp, cũng như tạo một biến self.conn
để quản lý các kết nối. Chúng tôi tạo một thể hiện của lớp này bằng cách chuyển đối tượng cấu hình của chúng tôi tới Cơ sở dữ liệu
from config import Config
db = Database[config]
Khởi tạo cơ sở dữ liệuVới lớp của chúng tôi được khởi tạo, chúng tôi đã sẵn sàng để nấu ăn
Dọn bàn
Phương thức đầu tiên chúng ta sẽ thêm vào lớp của mình sẽ được gọi là
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
0 để quản lý việc mở các kết nối đến cơ sở dữ liệu của chúng ta. Ở đây, chúng tôi thiết lập một chức năng để tách logic kết nối cơ bản và thông báo lỗi khỏi ứng dụng của chúng tôiimport sys
import pymysql
from loguru import logger
class Database:
"""Database connection class."""
...
def open_connection[self]:
"""Connect to MySQL Database."""
try:
if self.conn is None:
self.conn = pymysql.connect[
self.host,
user=self.username,
passwd=self.password,
db=self.dbname,
connect_timeout=5
]
except pymysql.MySQLError as e:
logger.error[e]
sys.exit[]
finally:
logger.info['Connection opened successfully.']
Phương thức mở kết nối cơ sở dữ liệuChúng tôi xem biến lớp của chúng tôi self.conn
để phục vụ như là đối tượng kết nối của chúng tôi. Bằng cách đặt kết nối trên chính lớp của chúng ta, chúng ta có thể cho phép tất cả các phương thức của lớp này hoạt động trên cùng một kết nối cơ sở dữ liệu thay vì mở và đóng kết nối cho mọi truy vấn
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
2 kiểm tra xem self.conn
đã tồn tại chưa. Nếu kết nối không tồn tại, chức năng của chúng tôi sẽ cố gắng kết nối với cơ sở dữ liệu MySQL của chúng tôi bằng thông tin đăng nhập đã cho. Chúng tôi cũng có một số logic ở đây để đưa ra lỗi nếu có sự cố xảy ra bằng cách tận dụng loại ngoại lệ class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
4 tích hợp sẵn của PyMySQL. Làm quen với việc nhìn thấy nhiều câu lệnh try/ngoại trừ/cuối cùng khi làm việc với cơ sở dữ liệuBây giờ chúng ta có thể chia sẻ
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
2 giữa tất cả các phương thức của lớp và chỉ kết nối mở khi cầnEntree
Bỏ qua những thứ nhàm chán, hãy tìm hiểu điều gì đó tốt đẹp. Chúng ta sẽ bắt đầu với một trường hợp sử dụng cơ bản. chọn tất cả các hàng từ một bảng
...
class Database:
"""Database connection class."""
...
def run_query[self, query]:
"""Execute SQL query."""
try:
self.open_connection[]
with self.conn.cursor[] as cur:
records = []
cur.execute[query]
result = cur.fetchall[]
for row in result:
records.append[row]
cur.close[]
return records
except pymysql.MySQLError as e:
print[e]
finally:
if self.conn:
self.conn.close[]
self.conn = None
logger.info['Database connection closed.']
Thực hiện truy vấn cơ sở dữ liệuclass Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
6 cố gắng mở kết nối bằng hàm class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
0 mà chúng ta đã tạo trước đó. Khi kết nối đó mở, chúng tôi có thể tự do chạy bất kỳ truy vấn nào chúng tôi muốnHàm của chúng tôi được truyền một tham số có tên là truy vấn, đại diện cho bất kỳ truy vấn SQL nào chúng tôi muốn chạy [AKA.
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
8]. Để thực hiện một truy vấn như vậy, chúng ta cần mở một con trỏ mà chúng ta thực hiện với dòng nàywith self.conn.cursor[] as cur:
...
Mở con trỏ kết nốiChúng tôi có thể chạy tất cả các truy vấn mà chúng tôi muốn trong khi cur đang mở. Hãy đá nó lên một notch
Chọn hàng dữ liệu
Bây giờ với cur mở, chúng ta có thể gọi một vài phương pháp chống lại cur
9. Gọiclass Database: """Database connection class.""" def __init__[self, config]: self.host = config.db_host self.username = config.db_user self.password = config.db_password self.port = config.db_port self.dbname = config.db_name self.conn = None ...
0 on cur sẽ chạy một truy vấn bên trong đối tượng con trỏ của chúng tafrom config import Config db = Database[config]
1. Sau khi chạy một truy vấn dẫn đến các hàng, chúng ta có thể thấy tất cả các hàng được trả về bởi truy vấn của chúng ta bằng cách gọifrom config import Config db = Database[config]
2 trên cur. Như bạn có thể thấy, chúng ta chỉ nên thực hiện một truy vấn cho mỗi con trỏ. Nếu không, chúng tôi sẽ viết đi viết lại kết quả của truy vấn trước đó. Cố gắng in kết quả củafrom config import Config db = Database[config]
3 sẽ dẫn đến một số nguyên duy nhất, đại diện cho số lượng hàng được tìm nạpfrom config import Config db = Database[config]
4. Không giống nhưfrom config import Config db = Database[config]
2,from config import Config db = Database[config]
6 chỉ tìm nạp hàng đầu tiên được truy vấn của chúng tôi trả về. Nếu có những trường hợp mà chúng tôi biết chỉ nên trả lại một bản ghi, thì nên sử dụngfrom config import Config db = Database[config]
7from config import Config db = Database[config]
8. Cuối cùng khi chúng ta hoàn thành truy vấn của mình, chúng ta nên đóng con trỏ bằngfrom config import Config db = Database[config]
9from config import Config db = Database[config]
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
6 giả định rằng truy vấn chúng tôi đang chuyển là truy vấn CHỌN, đó là lý do tại sao chúng tôi lưu kết quả vào một mảng. Nếu chúng tôi đang chạy một truy vấn CẬP NHẬT hoặc XÓA, điều này sẽ không có ý nghĩa gì vì sẽ không có gì được trả vềCập nhật hàng dữ liệu
Điều gì sẽ xảy ra nếu chúng ta không chọn dữ liệu mà thay vào đó sửa đổi dữ liệu đó?
def run_query[self, query]:
"""Execute SQL query."""
try:
self.conn = pymysql.connect[
self.host,
user=self.username,
passwd=self.password,
db=self.dbname,
connect_timeout=5
]
...
Thực hiện truy vấn cơ sở dữ liệuCó một vài điều mới ở đây
1. Chạyimport sys import pymysql from loguru import logger class Database: """Database connection class.""" ... def open_connection[self]: """Connect to MySQL Database.""" try: if self.conn is None: self.conn = pymysql.connect[ self.host, user=self.username, passwd=self.password, db=self.dbname, connect_timeout=5 ] except pymysql.MySQLError as e: logger.error[e] sys.exit[] finally: logger.info['Connection opened successfully.']
2 thực sự cam kết các thay đổi trong truy vấn của chúng tôi. Nếu bạn quên điều này, các thay đổi đối với dữ liệu của bạn sẽ không thực sự được lưu [điều này cũng áp dụng cho các câu lệnh XÓA và CHÈN]import sys import pymysql from loguru import logger class Database: """Database connection class.""" ... def open_connection[self]: """Connect to MySQL Database.""" try: if self.conn is None: self.conn = pymysql.connect[ self.host, user=self.username, passwd=self.password, db=self.dbname, connect_timeout=5 ] except pymysql.MySQLError as e: logger.error[e] sys.exit[] finally: logger.info['Connection opened successfully.']
3. Trả về số hàng bị ảnh hưởng bởi một truy vấn làm thay đổi dữ liệuimport sys import pymysql from loguru import logger class Database: """Database connection class.""" ... def open_connection[self]: """Connect to MySQL Database.""" try: if self.conn is None: self.conn = pymysql.connect[ self.host, user=self.username, passwd=self.password, db=self.dbname, connect_timeout=5 ] except pymysql.MySQLError as e: logger.error[e] sys.exit[] finally: logger.info['Connection opened successfully.']
Kết hợp những điều trên
Vì vậy, bây giờ chúng tôi có một phiên bản của
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
...
6 mong đợi các câu lệnh CHỌN và một phiên bản khác mong đợi các đột biến. Làm cách nào chúng ta có thể làm cho chức năng này đủ thông minh để xử lý cả hai trường hợp và trả về kết quả hợp lý nhất? ...
class Database:
"""Database connection class."""
...
def run_query[self, query]:
"""Execute SQL query."""
try:
self.open_connection[]
with self.conn.cursor[] as cur:
if 'SELECT' in query:
records = []
cur.execute[query]
result = cur.fetchall[]
for row in result:
records.append[row]
cur.close[]
return records
result = cur.execute[query]
self.conn.commit[]
affected = f"{cur.rowcount} rows affected."
cur.close[]
return affected
except pymysql.MySQLError as e:
logger[e]
sys.exit[]
finally:
if self.conn:
self.conn.close[]
self.conn = None
logger.info['Database connection closed.']
Thực hiện truy vấn cơ sở dữ liệuBây giờ chúng tôi có một chức năng xử lý cả hai kịch bản. Tất nhiên, việc triển khai này không hoàn toàn chính xác. nếu một trong các cột của bạn có tên CHỌN [hoặc thứ gì đó], bạn có thể gặp một số vấn đề. Đừng làm thế, tôi cho là vậy
Cho món tráng miệng
Hy vọng rằng bạn đã tìm thấy ngày ăn tối nhỏ của chúng tôi là hữu ích. Nếu bạn đang tìm kiếm một số nguồn sao chép và dán để tự mình bắt đầu với PyMySQL, vui lòng kiểm tra mã nguồn cho điều này trên Github tại đây. Nếu quá nhiều, vui lòng sao chép + dán bên dưới
import sys
import pymysql
from loguru import logger
class Database:
"""Database connection class."""
def __init__[self, config]:
self.host = config.db_host
self.username = config.db_user
self.password = config.db_password
self.port = config.db_port
self.dbname = config.db_name
self.conn = None
def open_connection[self]:
"""Connect to MySQL Database."""
try:
if self.conn is None:
self.conn = pymysql.connect[
self.host,
user=self.username,
passwd=self.password,
db=self.dbname,
connect_timeout=5
]
except pymysql.MySQLError as e:
logger.error[e]
sys.exit[]
finally:
logger.info['Connection opened successfully.']
def run_query[self, query]:
"""Execute SQL query."""
try:
self.open_connection[]
with self.conn.cursor[] as cur:
if 'SELECT' in query:
records = []
cur.execute[query]
result = cur.fetchall[]
for row in result:
records.append[row]
cur.close[]
return records
result = cur.execute[query]
self.conn.commit[]
affected = f"{cur.rowcount} rows affected."
cur.close[]
return affected
except pymysql.MySQLError as e:
logger[e]
sys.exit[]
finally:
if self.conn:
self.conn.close[]
self.conn = None
logger.info['Database connection closed.']
Toàn vănChúng tôi cảm ơn tất cả các bạn đã tham gia cùng chúng tôi trong cuộc phiêu lưu của những món ăn hấp dẫn này. Có thể dữ liệu của bạn sạch sẽ và dạ dày của bạn đầy đủ