Tôi đang thiết kế một ứng dụng GUI nhỏ để bọc một sqlite DB (các hoạt động CRUD đơn giản). Tôi đã tạo ra ba mô hình SQLAlchemy (m_person
, m_card.py
, m_loan.py
, tất cả trong một thư mục /models
) mà trước đó đã có đoạn mã sau ở phía trên cùng của mỗi người:Có thể thực thi mã khi một mô-đun được nhập không?
from sqlalchemy import Table, Column, create_engine
from sqlalchemy import Integer, ForeignKey, String, Unicode
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import backref, relation
engine = create_engine("sqlite:///devdata.db", echo=True)
declarative_base = declarative_base(engine)
metadata = declarative_base.metadata
này cảm thấy một chút sai (DRY) nên nó đã được đề xuất rằng tôi di chuyển tất cả các công cụ này ra cấp độ mô-đun (vào models/__init__.py
).
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Table, Column, Boolean, Unicode
from settings import setup
engine = create_engine('sqlite:///' + setup.get_db_path(), echo=False)
declarative_base = declarative_base(engine)
metadata = declarative_base.metadata
session = sessionmaker()
session = session()
..và nhập declarative_base
như vậy:
from sqlalchemy import Table, Column, Unicode
from models import declarative_base
class Person(declarative_base):
"""
Person model
"""
__tablename__ = "people"
id = Column(Unicode(50), primary_key=True)
fname = Column(Unicode(50))
sname = Column(Unicode(50))
Tuy nhiên tôi đã có rất nhiều phản hồi rằng thực thi mã như hàng nhập khẩu mô-đun như thế này là xấu? Tôi đang tìm kiếm một câu trả lời dứt khoát đúng cách để làm điều đó vì nó có vẻ như bằng cách cố gắng để loại bỏ sự lặp lại mã tôi đã giới thiệu một số thực hành xấu khác. Mọi phản hồi sẽ thực sự hữu ích.
(Dưới đây là get_db_path()
phương pháp từ settings/setup.py
cho đầy đủ như nó được gọi trong models/__init__.py
mã trên.)
def get_db_path():
import sys
from os import makedirs
from os.path import join, dirname, exists
from constants import DB_FILE, DB_FOLDER
if len(sys.argv) > 1:
db_path = sys.argv[1]
else:
#Check if application is running from exe or .py and adjust db path accordingly
if getattr(sys, 'frozen', False):
application_path = dirname(sys.executable)
db_path = join(application_path, DB_FOLDER, DB_FILE)
elif __file__:
application_path = dirname(__file__)
db_path = join(application_path, '..', DB_FOLDER, DB_FILE)
#Check db path exists and create it if not
def ensure_directory(db_path):
dir = dirname(db_path)
if not exists(dir):
makedirs(dir)
ensure_directory(db_path)
return db_path
2c của tôi, trong khi nói chung là OK để đặt mã init trong '__init __. Py' (đó là những gì nó có cho!), Đi xa như vậy để thiết lập URL cơ sở dữ liệu có vẻ sai với tôi. Nó có thể làm cho thử nghiệm khó khăn hơn. Dường như với tôi rằng những gì bạn nên làm là có một hàm 'init()' cho module. – cha0site
Tôi nghĩ rằng vấn đề ở đây là lớp cơ sở 'declarative_base' được tạo động và dường như phụ thuộc vào cơ sở dữ liệu. Tôi không biết làm thế nào sqlalchemy hoạt động, nhưng là nó không thể xác định các lớp mô hình trước khi thực hiện kết nối DB ?? Tôi khó có thể tin được điều đó. –
@NiklasB. 'Declarative_base' phụ thuộc vào" siêu dữ liệu "mà về cơ bản là động cơ sqlalchemy lõi. Nó không nhất thiết phải có bất kỳ mối quan hệ nào với cơ sở dữ liệu, mặc dù bạn có thể chọn cho nó một cái để đơn giản. – wberry