Các ứng dụng thường cần kết nối với các dịch vụ khác (cơ sở dữ liệu, bộ nhớ cache, API, v.v.). Đối với sự tỉnh táo và DRY, chúng tôi muốn giữ tất cả các kết nối này trong một mô-đun để phần còn lại của cơ sở mã của chúng tôi có thể chia sẻ các kết nối.Quản lý tạo kết nối bằng Python?
Để giảm soạn sẵn, sử dụng hạ lưu nên đơn giản:
# app/do_stuff.py
from .connections import AwesomeDB
db = AwesomeDB()
def get_stuff():
return db.get('stuff')
Và việc thiết lập kết nối cũng nên được đơn giản:
# app/cli.py or some other main entry point
from .connections import AwesomeDB
db = AwesomeDB()
db.init(username='stuff admin') # Or os.environ['DB_USER']
khung web như Django và Flask làm điều gì đó như thế này, nhưng cảm giác hơi khó chịu:
Connect to a Database in Flask, Which Approach is better? http://flask.pocoo.org/docs/0.10/tutorial/dbcon/
Một vấn đề lớn với điều này là chúng tôi muốn tham chiếu đến đối tượng kết nối thực tế thay vì proxy, bởi vì chúng tôi muốn giữ lại tab hoàn thành trong iPython và các môi trường dev khác.
Vì vậy, Right Way (tm) để làm điều đó là gì? Sau một vài lần lặp lại, đây là ý tưởng của tôi:
#app/connections.py
from awesome_database import AwesomeDB as RealAwesomeDB
from horrible_database import HorribleDB as RealHorribleDB
class ConnectionMixin(object):
__connection = None
def __new__(cls):
cls.__connection = cls.__connection or object.__new__(cls)
return cls.__connection
def __init__(self, real=False, **kwargs):
if real:
super().__init__(**kwargs)
def init(self, **kwargs):
kwargs['real'] = True
self.__init__(**kwargs)
class AwesomeDB(ConnectionMixin, RealAwesomeDB):
pass
class HorribleDB(ConnectionMixin, RealHorribleDB):
pass
Phòng để cải thiện: Thiết __connection ban đầu để một ConnectionProxy generic thay vì Không, mà bắt tất cả các truy cập thuộc tính và ném một ngoại lệ.
Tôi đã thực hiện khá nhiều điều thú vị ở đây về SO và trong các dự án PMNM khác nhau và chưa thấy bất cứ điều gì như thế này. Nó cảm thấy khá vững chắc, mặc dù nó có nghĩa là một loạt các mô-đun sẽ được instantiating đối tượng kết nối như là một tác dụng phụ tại thời gian nhập khẩu. Điều này sẽ thổi lên trong khuôn mặt của tôi? Có bất kỳ hậu quả tiêu cực nào khác đối với phương pháp này không?
Cảm ơn bạn đã trả lời kỹ lưỡng! Tôi đã không thực sự được coi là chủ đề an toàn và an toàn, tôi chắc chắn sẽ nghĩ về điều đó. Re: lỗi thông số kết nối, bắt tốt và sửa lỗi tốt. Re: khách hàng hồ bơi, cũng là một điểm tốt, nhưng ngay cả với một hồ bơi kết nối, bạn sẽ muốn tập trung khởi tạo và đảm bảo rằng bạn đang sử dụng cùng một hồ bơi trong suốt ứng dụng. – knite
Re: chức năng trợ giúp đơn giản, tôi xem xét cách tiếp cận này ban đầu. Nó nhanh chóng trở nên khó chịu do mỗi mô-đun cần nhập khẩu awesome_db * và * gọi nó. – knite