2011-07-07 30 views
7

Tôi có thể thiếu một cái gì đó hiển nhiên, nhưng tôi không thể tìm ra cách mã của tôi khác với các ví dụ khác nhau mà tôi thấy trong tài liệu trực tuyến cho MySQLdb.Tên bảng Python, MySQLdb và thoát?

Tôi khá mới để lập trình python, nhiều kinh nghiệm hơn với perl. Những gì tôi đang cố gắng làm là bắt đầu một số thói quen tốt nhất (như trong perl tôi luôn bắt đầu với 'sử dụng nghiêm ngặt; sử dụng cảnh báo'), vì vậy tôi đang cố gắng đảm bảo tôi tạo các chức năng có thể sử dụng lại trong một tệp độc lập (funct.py) để tiết kiệm thời gian cho tôi sau đó.

Tôi đã có chức năng này để lựa chọn hàng ngẫu nhiên từ một bảng:

def returnRandom(conn,countcol,table,field): 
    cursor = conn.cursor() 
    cursor.execute('SELECT MAX(%s) FROM %s',(countcol,table)) 
    maxRow = cursor.fetchone()[0] 
    cursor.execute("SELECT MIN(%s) FROM %s",(countcol,table)) 
    minRow = cursor.fetchone()[0] 
    randomId = random.randrange(minRow,maxRow+1,1) 
    cursor.execute("SELECT ? FROM ? WHERE id >=? LIMIT 1",field,table,randomId) 
    return cursor.fetchone()[0] 

Nó đang được gọi là như thế này:

msg = funct.returnRandom(conn,"id","testtable","data") 

Đáng tiếc là nó lỗi ra với: _mysql_exceptions.ProgrammingError: (1064, "Bạn có lỗi trong cú pháp SQL của bạn; hãy kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn cho cú pháp đúng để sử dụng gần '' testtable '' ở dòng 1")

Nếu tôi đặt testtable tại ở vị trí của% s trên đường thực hiện, Truy vấn sẽ chạy nhưng có vẻ như nó chạy

SELECT MAX('id') FROM testtable; 

mà của 'id' trở về khóa học.

Được cung cấp cả hai mục đó giống như trích dẫn các mục nhập% s khi nó cố thực thi chúng. Tôi đã tự hỏi liệu có ai có thể giải thích làm thế nào tôi có thể ngừng làm điều đó, hay làm thế nào tôi thực sự đang làm những gì tôi đang cố gắng đạt được? Tôi muốn hàm càng chung càng tốt, do đó, dựa vào dữ liệu được truyền cho nó khi nó được gọi.

chỉnh sửa: Tôi nên thêm, nếu tôi thay thế? nhãn hiệu:

.... 
    cursor.execute('SELECT MAX(?) FROM ?',(countcol,table)) 
File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 151, in execute 
    query = query % db.literal(args) 
TypeError: not all arguments converted during string formatting 

Trả lời

2

Bạn không thể sử dụng DB-API cho siêu dữ liệu; bạn sẽ cần tự thay thế bên ngoài cuộc gọi execute().

query = 'SELECT MAX(%%s) FROM `%s`' % (table,) 
cursor.execute(query, (countcol,)) 

Rõ ràng bạn không nên làm điều này nếu table xuất phát từ nguồn bên ngoài.

+2

Đó là lý tưởng những gì tôi đang cố gắng để tránh. Tôi đã đạt được chức năng định dạng tương tự bằng cách sử dụng, nhưng tôi muốn làm điều đó một chút an toàn hơn. – Twirrim

0

MySQLdb có thể trích dẫn tên bảng của bạn bằng dấu nháy đơn thay vì dấu gạch chéo ngược. Hãy thử điều này

cursor.execute('SELECT MAX(%%s) FROM `%s`' % table,(countcol)) 
+0

Không, điều đó cũng không thành công, vẫn đang tìm kiếm cơ sở dữ liệu.không thể '! – Twirrim

+1

Câu trả lời này về cơ bản giống với @ Ignacio's. Tôi không chắc làm thế nào bạn có thể kết thúc với dấu ngoặc kép. Bạn có gõ backticks quanh '% s' ở cuối chuỗi được trích dẫn không? –

-1

Thú vị. Nhưng trong manual có một vài ví dụ. Có lẽ nó là một cái gì đó tương tự.

c=db.cursor() 
max_price=5 
c.execute("""SELECT spam, eggs, sausage FROM breakfast 
      WHERE price < %s""", (max_price,)) 

In this example, max_price=5 Why, then, use %s in the string? Because MySQLdb will convert it to a SQL literal value, which is the string '5'. When it's finished, the query will actually say, "...WHERE price < 5".

c.executemany(
     """INSERT INTO breakfast (name, spam, eggs, sausage, price) 
     VALUES (%s, %s, %s, %s, %s)""", 
     [ 
     ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95), 
     ("Not So Much Spam Plate", 3, 2, 0, 3.95), 
     ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95) 
     ]) 

Here we are inserting three rows of five values. Notice that there is a mix of types (strings, ints, floats) though we still only use %s. And also note that we only included format strings for one row. MySQLdb picks those out and duplicates them for each row.

+2

Sự cố là thoát tên bảng, không phải giá trị cột. – augurar

Các vấn đề liên quan