使用 SQLAlchemy 和 Postgresql 从长度未知的 table 名称列表构建查询
Build query from list of table names with unknown length using SQLAlchemy and Postgresql
我正在处理时间序列数据,我试图避免在单个记录的每一行上都存在多对一关系 table,其中所有记录都混合在一起(因为系列都有不同的列数)。
相反,我想在多个 table 之间拆分记录,以将各个数据系列分开。
我有很多这样的table:
# series 1 record tables:
CREATE TABLE records_1 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION
#... more columns
);
CREATE TABLE records_2 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION
#... more columns
);
CREATE TABLE records_34 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION
#... more columns
);
# series 2 record tables
CREATE TABLE records_101 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION,
height DOUBLE PRECISION
#... more columns
);
CREATE TABLE records_102 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION,
height DOUBLE PRECISION
#... more columns
);
然后我有一个 class 和一个字符串,表示与 class 关联的 table 名称:
class Serie(db.Model):
id = db.Column(db.Integer, primary_key=True)
record_tables = db.Column(db.String(255))
示例:
s1 = Serie()
s1.record_tables = 'records_1, records_2, records_34'
s2 = Serie()
s2.record_tables = 'records_101, records_102'
我希望能够根据 record_tables 字符串 select 与给定系列相关联的所有记录。拆分和去除空格很容易,但我将如何动态构建查询?
类似于 "for each table in record_tables_list, select all records from table and return all records from all tables in list",但在一个 sql 查询中,而不是将结果附加到 python 中的列表(我想这会更慢)。
我想我应该使用 UNION,因为我已经在 SQL 中手动重新创建了这样的查询。但是如何在 Serie.record_tables 中使用未知数量的 table 名称呢?
更新:
好的,所以原始查询似乎在加入经过清理的 record_tables 列表时有效(这取决于用户输入(我自己的输入)所以我必须清理它以删除拼写错误等):
tables = ', '.join([x.strip() for x in record_tables.split(',')])
raw_query = 'SELECT * FROM ' + tables
results = db.engine.execute(raw_query)
for row in raw_query:
print row # (1L, 123.0, 1L, 456.0)
编辑:不,这不起作用。嗯。
class Serie(Base):
__tablename__ = 'serie'
id = Column(Integer, primary_key=True)
record_tables = Column(String(255))
@property
def get_records(self):
sess = object_session(self)
tables = [x.strip() for x in self.record_tables.split(',')]
raw_query = '\nUNION ALL\n'.join(
'SELECT * FROM ' + table for table in tables)
results = sess.execute(raw_query).fetchall()
return results
这假设在 Serie
中配置的所有 记录 表具有相同的列并且列顺序相同。
我正在处理时间序列数据,我试图避免在单个记录的每一行上都存在多对一关系 table,其中所有记录都混合在一起(因为系列都有不同的列数)。
相反,我想在多个 table 之间拆分记录,以将各个数据系列分开。
我有很多这样的table:
# series 1 record tables:
CREATE TABLE records_1 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION
#... more columns
);
CREATE TABLE records_2 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION
#... more columns
);
CREATE TABLE records_34 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION
#... more columns
);
# series 2 record tables
CREATE TABLE records_101 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION,
height DOUBLE PRECISION
#... more columns
);
CREATE TABLE records_102 (
id BIGSERIAL PRIMARY KEY,
level DOUBLE PRECISION,
height DOUBLE PRECISION
#... more columns
);
然后我有一个 class 和一个字符串,表示与 class 关联的 table 名称:
class Serie(db.Model):
id = db.Column(db.Integer, primary_key=True)
record_tables = db.Column(db.String(255))
示例:
s1 = Serie()
s1.record_tables = 'records_1, records_2, records_34'
s2 = Serie()
s2.record_tables = 'records_101, records_102'
我希望能够根据 record_tables 字符串 select 与给定系列相关联的所有记录。拆分和去除空格很容易,但我将如何动态构建查询?
类似于 "for each table in record_tables_list, select all records from table and return all records from all tables in list",但在一个 sql 查询中,而不是将结果附加到 python 中的列表(我想这会更慢)。
我想我应该使用 UNION,因为我已经在 SQL 中手动重新创建了这样的查询。但是如何在 Serie.record_tables 中使用未知数量的 table 名称呢?
更新:
好的,所以原始查询似乎在加入经过清理的 record_tables 列表时有效(这取决于用户输入(我自己的输入)所以我必须清理它以删除拼写错误等):
tables = ', '.join([x.strip() for x in record_tables.split(',')])
raw_query = 'SELECT * FROM ' + tables
results = db.engine.execute(raw_query)
for row in raw_query:
print row # (1L, 123.0, 1L, 456.0)
编辑:不,这不起作用。嗯。
class Serie(Base):
__tablename__ = 'serie'
id = Column(Integer, primary_key=True)
record_tables = Column(String(255))
@property
def get_records(self):
sess = object_session(self)
tables = [x.strip() for x in self.record_tables.split(',')]
raw_query = '\nUNION ALL\n'.join(
'SELECT * FROM ' + table for table in tables)
results = sess.execute(raw_query).fetchall()
return results
这假设在 Serie
中配置的所有 记录 表具有相同的列并且列顺序相同。