Python Postgresql分区和sqlalchemy
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
#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我正试图扩展你的代码。如果你能回答这个问题,那将很有帮助。