从Schema中的每个表中获取所有单列

时间:2015-05-21 21:38:48

标签: python postgresql sqlalchemy

在我们的系统中,我们有1000多个表,每个表都有一个' date'包含DateTime对象的列。我想获得一个列表,其中包含所有表中存在的每个日期。我确信应该有一个简单的方法来做到这一点,但我对postgresql或sqlalchemy的知识非常有限。

在postgresql中,我可以在两个表上进行完全连接,但对于单个公共字段,似乎没有办法在模式中的每个表上进行连接。

然后我尝试用sqlalchemy在python中以编程方式解决这个问题。对于每个表格,我确实为“日期”创建了一个选择区别。列,然后将该选择列表设置为CompoundSelect对象的choices属性,并执行。正如人们可能从一个丑陋的暴力查询中得到的那样,它现在已经运行了一个小时左右,而且我不确定它是否在某个地方默默地打破并且永远不会返回。

有没有干净,更好的方法来做到这一点?

2 个答案:

答案 0 :(得分:2)

您肯定希望在服务器上执行此操作,而不是在应用程序级别执行此操作,因为应用程序和服务器之间存在多次往返,并且可能会在中间结果中重复数据。

由于您需要处理1,000多个表,因此您应该使用系统目录并动态查询表。您需要一个有效的功能:

CREATE FUNCTION get_all_dates() RETURNS SETOF date AS $$
DECLARE
  tbl    name;
BEGIN
  FOR tbl IN SELECT 'public.' || tablename FROM pg_tables WHERE schemaname = 'public' LOOP
    RETURN QUERY EXECUTE 'SELECT DISTINCT date::date FROM ' || tbl;
  END LOOP
END; $$ LANGUAGE plpgsql;

这将处理public架构中的所有表格;根据需要改变。如果表是多个模式,则需要在存储表的位置插入附加逻辑,或者可以使模式名称成为函数的参数并多次调用函数并UNION结果。

请注意,您可能会从多个表中获得重复的date个。这些重复项可以在调用函数的语句中清除:

SELECT DISTINCT * FROM get_all_dates() ORDER BY 1;

该函数在内存中创建结果集,但如果1,000+表中行中不同日期的数量非常大,则结果将写入磁盘。如果您希望这种情况发生,那么最好在函数开头创建一个临时表并将日期插入该临时表中。

答案 1 :(得分:1)

结束恢复到之前使用SqlAlchemy运行查询的解决方案。这使我可以并行化并快速运行 little ,因为它确实是一个非常大的查询。

我对帮助此查询的数据集了解了一些事情 - 我只想要每个表中的不同日期,并且日期是我的集合中的PK。我最终使用this wiki page的方法。在查询中发送的代码如下所示:

WITH RECURSIVE t AS (
(SELECT date FROM schema.tablename ORDER BY date LIMIT 1) 
UNION ALL SELECT (SELECT knowledge_date FROM schema.table WHERE date > t.date ORDER BY date LIMIT 1)
FROM t WHERE t.date IS NOT NULL)
SELECT date FROM t WHERE date IS NOT NULL;

我将该查询的结果拖到我所有日期的列表中(如果它们已经不在列表中),然后将其保存以供日后使用。它可能只需要在pgsql控制台中运行它就可以了,但是我在本地保存比在必须查询db中的临时表更容易。