使用很多connection.cursor()

时间:2016-11-13 17:38:47

标签: postgresql psycopg2

我想一次从一个数据库中的3个表中获取数据。我使用了3个conn.cursor()..是否有任何复杂的方法可以做到这一点?

            conn = psycopg2.connect(database="plottest", user="postgres")
            self.statusbar.showMessage("Database opened Sucessfully", 1000)
            cur = conn.cursor()
            cur1 = conn.cursor()
            cur2 = conn.cursor()
            cur.execute("SELECT id ,actual  from \"%s\" " % date)
            rows = cur.fetchall()
            cur1.execute("SELECT qty from DAILY where date = \'%s\'" % date)
            dailyqty = cur1.fetchone()
            cur2.execute("SELECT qty from MONTHLY where month = \'%s\'" % month)
            monthqty = cur2.fetchone()   

2 个答案:

答案 0 :(得分:3)

Awoogah awoogah,SQL注入警告!不要使用字符串插值编写代码。如果有人使用“日期”');-- DROP TABLE DAILY;--调用您的代码,会发生什么?

使用绑定参数。总是

唯一的例外是动态标识符,例如上面的情况,您似乎使用以当前日期命名的表。在这种情况下,你必须 "double quote"他们并加倍任何包含的双引号。在您的情况下,这意味着date应该是date.replace('"', '""'),您可以将其替换为SQL。

现在,回到我们的常规节目。

由于您从每个光标fetchall,您可以重新使用它。每次都不需要新的游标。

如果需要,您还可以使用UNION ALL组合每日和每月统计信息。我在过程中修复了大小写和参数绑定:

cur.execute("""SELECT 1, qty FROM daily WHERE date = %s
               UNION ALL
               SELECT 2, qty FROM monthly WHERE month = %s
               ORDER BY 1""",
            (date, month))

请注意,不使用字符串插值,而是将2元组参数传递给psycopg2以直接绑定。参数周围不需要引号,psycopg2会根据需要添加它们。

这可以通过捆绑两个查询来避免客户端 - 服务器往返。额外的列和ORDER BY在技术上是必需的,因此您可以安全地假设第一行是每日结果,第二行是每月。实际上,PostgreSQL不会使用UNION ALL重新排序它们。

答案 1 :(得分:1)

你可以结合使用

SELECT a1 FROM t1 WHERE b1 = 'v1';

SELECT a2 FROM t2 WHERE b2 = 'v2';

这样的单一陈述:

SELECT t1.a1, t2.a2 FROM t1, t2
   WHERE t1.b1 = 'v1' AND t2.b2 = 'v2';

前提是两个查询只返回一行。