Я разрабатываю небольшое приложение GUI для обертывания базы данных sqlite (простые операции CRUD). Я создал три модели sqlalchemy (m_person
, m_card.py
, m_loan.py
, все в папке /models
) и ранее имел следующий код вверху каждого из них:
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
Это немного ошиблось (DRY), поэтому было предложено переместить все это на уровень модуля (в 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()
.. и импортируйте declarative_base
так:
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))
Однако у меня было много отзывов о том, что выполнение кода, поскольку модуль импортирует, как это плохо? Я ищу окончательный ответ на правильный способ сделать это, как кажется, пытаясь удалить повторение кода. Я представил некоторые другие плохие методы. Любая обратная связь будет действительно полезна.
(Ниже приведен метод get_db_path()
из settings/setup.py
для полноты, так как он вызывается в приведенном выше коде models/__init__.py
.)
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