2016-11-13 30 views
1

我想从一个数据库中的3个表中一次获取数据。我使用了3 conn.cursor()它..有没有什么复杂的方法来做到这一点?使用多个connection.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() 

回答

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重新排序。

+0

非常感谢您的建议。我在2周前开始使用PostgreSQL,我仍然处于noob级别。我会学习并尝试你所说的。再次感谢!! – Bodhi94

+1

@VibhuthaKumarage无后顾之忧。 SQL注入事件适用于所有SQL数据库。习惯于根据绑定参数进行思考,从查询文本中分离数据。请参阅http://bobby-tables.com/和https://en.wikipedia.org/wiki/SQL_injection。 –

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'; 

提供了两种查询返回一行。