【发布时间】:2014-05-07 10:06:45
【问题描述】:
我有许多(约 2000 个)带有时间序列数据的位置。每个时间序列都有数百万行。我想将这些存储在 Postgres 数据库中。我目前的方法是为每个位置时间序列创建一个表,以及一个存储每个位置信息(坐标、海拔等)的元表。我正在使用 Python/SQLAlchemy 创建和填充表。我想在元表和每个时间序列表之间建立关系,以执行诸如“选择在日期 A 和日期 B 之间具有数据的所有位置”和“选择日期 A 的所有数据并导出带有坐标的 csv”之类的查询。创建多个具有相同结构(只是名称不同)并与元表有关系的表的最佳方法是什么?还是应该使用不同的数据库设计?
目前我正在使用这种方法来生成很多类似的映射:
from sqlalchemy import create_engine, MetaData
from sqlalchemy.types import Float, String, DateTime, Integer
from sqlalchemy import Column, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, backref
Base = declarative_base()
def make_timeseries(name):
class TimeSeries(Base):
__tablename__ = name
table_name = Column(String(50), ForeignKey('locations.table_name'))
datetime = Column(DateTime, primary_key=True)
value = Column(Float)
location = relationship('Location', backref=backref('timeseries',
lazy='dynamic'))
def __init__(self, table_name, datetime, value):
self.table_name = table_name
self.datetime = datetime
self.value = value
def __repr__(self):
return "{}: {}".format(self.datetime, self.value)
return TimeSeries
class Location(Base):
__tablename__ = 'locations'
id = Column(Integer, primary_key=True)
table_name = Column(String(50), unique=True)
lon = Column(Float)
lat = Column(Float)
if __name__ == '__main__':
connection_string = 'postgresql://user:pw@localhost/location_test'
engine = create_engine(connection_string)
metadata = MetaData(bind=engine)
Session = sessionmaker(bind=engine)
session = Session()
TS1 = make_timeseries('ts1')
# TS2 = make_timeseries('ts2') # this breaks because of the foreign key
Base.metadata.create_all(engine)
session.add(TS1("ts1", "2001-01-01", 999))
session.add(TS1("ts1", "2001-01-02", -555))
qs = session.query(Location).first()
print qs.timeseries.all()
这种方法有一些问题,最值得注意的是,如果我创建多个TimeSeries,则外键不起作用。以前我使用过一些变通方法,但这一切似乎都是一个大技巧,我觉得必须有更好的方法来做到这一点。我应该如何组织和访问我的数据?
【问题讨论】:
标签: python sql database sqlalchemy