Python Postgresql分区和sqlalchemy

Python Postgresql分区和sqlalchemy,python,postgresql,sqlalchemy,postgresql-12,Python,Postgresql,Sqlalchemy,Postgresql 12,SQLAlchemy文档如何创建分区表。但它并没有解释如何创建分区 如果我有这个: #Skipping create_engine and metadata Base = declarative_base() class Measure(Base): __tablename__ = 'measures' __table_args__ = { postgresql_partition_by: 'RANGE (log_date)' } city_id

SQLAlchemy文档如何创建分区表。但它并没有解释如何创建分区

如果我有这个:

#Skipping create_engine and metadata
Base = declarative_base()

class Measure(Base):
    __tablename__ = 'measures'
    __table_args__ = {
        postgresql_partition_by: 'RANGE (log_date)'
    }
    city_id = Column(Integer, not_null=True)
    log_date = Columne(Date, not_null=True)
    peaktemp = Column(Integer)
    unitsales = Column(Integer)

class Measure2020(Base):
    """How am I suppposed to declare this ? """
我知道我将要做的大部分工作都是从logdate在XX和YY之间的度量值中选择*。但这似乎很有趣。

您可以使用两个类都可以继承的。 然后使用一个附加表分区

from sqlalchemy import event

class MeasureMixin:
    city_id = Column(Integer, not_null=True)
    log_date = Column(Date, not_null=True)
    peaktemp = Column(Integer)
    unitsales = Column(Integer)

class Measure(MeasureMixin, Base):
    __tablename__ = 'measures'
    __table_args__ = {
        postgresql_partition_by: 'RANGE (log_date)'
    }

class Measure2020(MeasureMixin, Base):
    __tablename__ = 'measures2020'

Measure2020.__table__.add_is_dependent_on(Measure.__table__)

event.listen(
    Measure2020.__table__,
    "after_create",
    DDL("""ALTER TABLE measures ATTACH PARTITION measures2020
VALUES FROM ('2020-01-01') TO ('2021-01-01');""")
)

我也有类似的问题。我发现@moshevi的答案非常有用,并最终对它进行了一些推广,因为我有许多表要分区

from sqlalchemy import event

class MeasureMixin:
    city_id = Column(Integer, not_null=True)
    log_date = Column(Date, not_null=True)
    peaktemp = Column(Integer)
    unitsales = Column(Integer)

class Measure(MeasureMixin, Base):
    __tablename__ = 'measures'
    __table_args__ = {
        postgresql_partition_by: 'RANGE (log_date)'
    }

class Measure2020(MeasureMixin, Base):
    __tablename__ = 'measures2020'

Measure2020.__table__.add_is_dependent_on(Measure.__table__)

event.listen(
    Measure2020.__table__,
    "after_create",
    DDL("""ALTER TABLE measures ATTACH PARTITION measures2020
VALUES FROM ('2020-01-01') TO ('2021-01-01');""")
)
首先,创建一个元类,如下所示:

从sqlalchemy.ext.declarative导入DeclarativeMeta 从sqlalchemy.sql.ddl导入ddl 从sqlalchemy导入事件 类PartitionByYearMetaDeclarativeMeta: 定义新的cls、clsname、bases、ATTR、*、分区依据: @类方法 def get_partition_namecls_,键: “措施”->“措施2020”可根据需要定制 返回f'{cls.\uuuuu tablename.\uuu}{key}' @类方法 def创建分区CLS,键: 如果密钥不在cls分区中: 分区=类型 f'{clsname}{key}',类名,仅在内部使用 基地,, {'''u tablename':cls.get\u partition\u namekey} 分区.\uuuuu表\uuuuu.add\u依赖于\uu表\uuu__ 听我说 分区。表, “创建”之后, DDL 对于非年份范围,请修改下面的“从”和“到” F 更改表{cls.\uuuuu tablename} 附加分区{PARTITION.\uuuu tablename\uuuuu} 对于从{key}-01-01'到{key+1}-01-01'的值; cls分区[键]=分区 返回cls分区[键] 属性更新 { 对于非范围分区,请按下面的键修改“postgresql分区” “\uuuu表参数”:attrs.get”“uuuu表参数”, +dictpostgresql_partition_by=f'RANGE{partition_by}',, '分区':{}, “分区依据”:分区依据, “获取分区名称”:获取分区名称, “创建分区”:创建分区 } 返回super.\uuuu new\uuuu cls、clsname、Base、attrs 接下来,对于模型中要分区的任何表:

类测量值: 这些柱子需要被拉到这个混合器里 注意:任何外键列都需要按如下方式包装: @声明属性 def city_idself: return ColumnForeignKey'cities.id',not_null=True log_date=ColumnDate,not_null=True peaktemp=ColumnInteger unitsales=ColumnInteger 类MeasureMeasureMixin,Base,元类=PartitionByYearMeta,partition_by='logdate': __tablename_uu='measures' 这使得添加更多表和按任意数量的值分区变得容易

动态创建新分区的工作原理如下:

确保提交当前打开的任何会话,即使是对于select查询: session.commit Partition=Measure.create_partition2020 如果不是engine.Dialogue.has\u tablePartition.\u table\u.name: 分区。\表\创建绑定=引擎
现在创建了key 2020的分区,可以插入该年的值。

对于数据库分区PostgreSQL或MySQL,可以尝试使用architect包。它与一系列ORM库一起工作,包括SQLAlchemy。下面是PostgreSQL的一个示例-。支持多种分区类型,因此希望它能够满足您案例的要求。

我认为在这种情况下,您最好的选择可能是原始SQL。看到其他人在处理此问题正在验证。Mike Bayer在这里给出了一个答案:Nice甚至可以自动创建分区。我应该在Measure2020和Measure之间添加一个依赖项。会很好的!下一步是对其进行更多的概括,以允许不同类型的分区。然后可能是一个请求?@moshevi我正试图扩展你的代码。如果你能回答这个问题,那将很有帮助。