【问题标题】:How to split up SQLAlchemy ORM and functions into two different files如何将 SQLAlchemy ORM 和函数拆分为两个不同的文件
【发布时间】:2021-08-30 03:20:29
【问题描述】:

我为一个应用程序编写了一些代码,其中一些信息存储在 SQLite3 数据库中。因此我使用了 SQLAlchemy 并设置了对象关系映射器,例如:

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Date
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# Setting up SQLAlchemy to connect to the local SQLite3 database
Base = declarative_base()
engine = create_engine('sqlite:///:main:', echo=True)
Base.metadata.create_all(bind=engine)
Session = sessionmaker(bind=engine)
session = Session()

在数据库中存储信息的两个主要类如下所示:

class Habit(Base):    
    __tablename__ = 'habit'
    habit_id = Column('habit_id', Integer, primary_key=True)
    name = Column('name', String, unique=True)
    periodicity = Column('periodicity', String)
    start_date = Column('start_date', Date)

class HabitEvent(Base):
    __tablename__ = 'habit_event'
    event_id = Column('event_id', Integer, primary_key=True)
    date = Column('date', Date)
    habit_id = Column('fk_habit_id', Integer, ForeignKey(Habit.habit_id))

这就是我的 main.py 的样子。现在我写了一些函数来添加 Habit 或 HabitEvent 的类对象并分析它们。这是一个例子:

def get_habits():
    """Lists all habits, including habit id, periodicity and start date."""
    
    habits = session.query(Habit).all()
    for habit in habits:
        print(str(habit.habit_id)+', '+str(habit.name) + ', ' 
              + str(habit.periodicity) +', Start Date: '
              + str(habit.start_date.strftime('%A, %B %d, %Y')))

现在我想将函数与 ORM 设置分开。我想要一个包含 ORM 设置和类的 main.py 和一个包含所有功能的 analytics.py。当我这样做并将函数从 analytis.py 导入到 main.py 并尝试调用它们时,它显然不知道 Habit 和 HabitEvent 类,因为它们没有在 analytics.py 中定义。

这是我的最后一个问题:是否有可能将 ORM 和分析函数拆分为两个建议的文件?还是它们必须是同一个文件的一部分?

【问题讨论】:

    标签: python sqlalchemy orm


    【解决方案1】:

    是的,它们可以分成多个文件。

    一种方法是将会话和模型传递给函数:

    def get_habits(session, Habit):
        """Lists all habits, including habit id, periodicity and start date."""
    
        habits = session.query(Habit).all()
        for habit in habits:
            print(str(habit.habit_id)+', '+str(habit.name) + ', ' 
                  + str(habit.periodicity) +', Start Date: '
                  + str(habit.start_date.strftime('%A, %B %d, %Y')))
    

    main.py 文件中,您可以在导入后调用此函数,如下所示:

    get_habits(session, Habit)
    

    sessionsession = Session()Habit 是您要在函数中使用的模型(类)。

    【讨论】:

    • 这样做,python 会期望 session 的参数并给出没有收到值的错误。
    • 你能告诉我错误信息和你调用函数的方式吗?
    • 我按照您建议的方式更改了函数,并使用 Google 的 Fire CLI 通过 bash 调用该函数。我尝试了以下几行。 python main.py get_habits 在这里我得到一个错误提示:ERROR: The function received no value for the required argument: session 当我使用 sessionHabit 作为参数时,我得到以下错误:habits = session.query(Habit).all() AttributeError: 'str' object has no attribute 'query' 因为 python 将会话作为字符串。
    【解决方案2】:

    我通过将代码拆分成多个文件解决了这个问题:

    • main.py 包含 CLI 并从 analytics.py 导入所有函数
    • orm.py 包含对象关系映射器设置
    • classes.py 包含 orm 的类并从 orm.py 导入 Base
    • analytics.py 包含来自 classes.py 的所有函数和类的导入以及来自 orm.py 的会话

    【讨论】:

      猜你喜欢
      • 2014-07-31
      • 1970-01-01
      • 2015-07-21
      • 2017-09-09
      • 1970-01-01
      • 2021-12-30
      • 2022-10-15
      • 1970-01-01
      • 2018-06-17
      相关资源
      最近更新 更多