pandas 如何用静态方法扩展SQLAchemy基类

sirbozc5  于 2023-01-01  发布在  其他
关注(0)|答案(2)|浏览(142)

我有多个类似于以下内容的类:

class Weather(Base):
    __tablename__ = "Weather"
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    temperature = Column(Integer)
    humidity = Column(Integer)
    wind_speed = Column(Float)
    wind_direction = Column(String)

我想添加一个方法df(),它返回那个表的Pandas Dataframe ,我知道我可以这样写:

class Weather(Base):
   __tablename__ = "Weather"
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    temperature = Column(Integer)
    humidity = Column(Integer)
    wind_speed = Column(Float)
    wind_direction = Column(String)

    @staticmethod
    def df():
        with engine.connect() as conn:
            return pd.read_sql_table(Weather.__tablename__ , conn)

但是我想为每个表实现这个。我想如果我可以用这个方法扩展基类,我应该能够实现它一次,并在每个类中使用它。我所尝试的一切都失败了,因为我没有访问__tablename__属性。

解决方案我得到了两种答案的混合。我使用了@snakecharmerb建议的第一种方法(它允许在不修改其余代码的情况下引入更改)和@RomanPerekhrest建议的@classmethod(这是我遗漏的一点)。

class MyBase:
    __tablename__ = None

    @classmethod
    def df(cls):
        with engine.connect() as conn:
            return pd.read_sql_table(cls.__tablename__ , conn)

Base = declarative_base(cls=MyBase)
axkjgtzd

axkjgtzd1#

您可以通过向declarative_base函数传递一个自定义类来完成此操作:

class MyBase:
    __abstract__ = True

    @staticmethod
    def df():
        with engine.connect() as conn:
            return pd.read_sql_table(Weather.__tablename__ , conn)

Base = orm.declarative_base(cls=MyBase)

class MyModel(Base):
    __tablename__ = 'tbl'
    ...

或者,您可以创建一个mixin来提供静态方法,并让类有选择地从该方法继承。

class DFMixin:
    @staticmethod
    def df():
        with engine.connect() as conn:
            return pd.read_sql_table(Weather.__tablename__ , conn)

class MyModel(Base, DFMixin):
    __tablename__ = 'tbl'
    ...

如果不是所有的模型都需要 Dataframe 功能,mixin可以为您提供更多的灵活性。

s3fp2yjn

s3fp2yjn2#

声明一个辅助类(比如DfBase),类方法df(cls)具有所需的行为。
然后,每个派生类将通过引用派生类本身的cls对象无缝地访问其__tablename__属性。

class DfBase:
    __tablename__ = None

    @classmethod
    def df(cls):
        with engine.connect() as conn:
            return pd.read_sql_table(cls.__tablename__ , conn)

class Weather(Base, DfBase):
    __tablename__ = "Weather"
    ...

相关问题