PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Danh sách Python đến Mảng PostgreSQL

Lưu ý rằng với psycopg2 bạn không cần thực hiện bất kỳ xử lý chuỗi nào cho mảng. Đây được coi là hành vi xấu vì nó dễ xảy ra lỗi và - trong trường hợp xấu nhất - có thể dẫn đến việc mở các cuộc tấn công tiêm! Bạn nên luôn sử dụng các tham số ràng buộc. Trong đoạn mã dưới đây, tôi sẽ tạo một bảng mới chỉ có một cột với kiểu TEXT[] (như trong câu hỏi ban đầu của bạn). Sau đó, tôi sẽ thêm một hàng mới và cập nhật tất cả chúng. Vì vậy, bạn sẽ thấy cả INSERTUPDATE hoạt động (mặc dù cả hai đều khá giống nhau).

Có một lỗi trong Python nếu bạn cập nhật chỉ với một giá trị:cur.execute mong đợi câu lệnh SQL làm đối số đầu tiên và một có thể lặp lại chứa các tham số được ràng buộc dưới dạng đối số thứ hai. Sau đây sẽ không công việc:

from psycopg2 import connect

conn = connect('dbname=exhuma')
cur = conn.cursor()
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values))
conn.commit()

Lý do là (new_values) được python xem là new_values (các parens bị bỏ trong trường hợp này, chúng không được coi là tuple). Điều này sẽ dẫn đến lỗi bạn cung cấp 3 giá trị ('a' , 'b''c' ) dưới dạng các giá trị được liên kết, nhưng chỉ có một trình giữ chỗ (%s ) trong truy vấn. Thay vào đó, bạn phải chỉ định nó như sau (chú ý dấu phẩy được thêm vào cuối):

from psycopg2 import connect

conn = connect('dbname=exhuma')
cur = conn.cursor()
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values,))
conn.commit()

Điều này sẽ làm cho Python thấy (new_values,) dưới dạng bộ tuple (là một phần tử có thể lặp lại) với một phần tử, phần tử này khớp với các phần tử giữ vị trí truy vấn. Để có giải thích chi tiết hơn về dấu phẩy ở cuối, hãy xem tài liệu chính thức về bộ giá trị.

Ngoài ra, bạn cũng có thể viết [new_values] thay vì (new_values,) , nhưng - theo ý kiến ​​của tôi - (new_values,) sạch hơn vì các bộ giá trị là bất biến, trong khi danh sách có thể thay đổi.

Đây là bảng mà tôi đã kiểm tra:

CREATE TABLE foo (
    values TEXT[]
);

Và đây là mã Python cả việc chèn và cập nhật giá trị:

from psycopg2 import connect


conn = connect('dbname=exhuma')
cur = conn.cursor()

cur.execute('INSERT INTO foo VALUES (%s)', (['a', 'b'], ))

print('>>> Before update')
cur.execute('SELECT * FROM foo')
for row in cur:
    print(type(row[0]), repr(row[0]))

print('>>> After update')

cur.execute('UPDATE foo SET example_values = %s',
            (['new', 'updated', 'values'],))

cur.execute('SELECT * FROM foo')
for row in cur:
    print(type(row[0]), repr(row[0]))

cur.close()
conn.commit()
conn.close()

Trên mỗi lần thực thi, mã sẽ chèn một hàng mới có cùng các giá trị mảng, sau đó thực hiện cập nhật mà không có WHERE , vì vậy tất cả các giá trị đều được cập nhật. Sau một vài lần thực thi, tôi cho kết quả sau:

>>> Before update
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['a', 'b']")
>>> After update
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để giải phóng các khóa hàng Postgres có thể có?

  2. Mẹo lưu trữ bản sao lưu PostgreSQL trên Amazon AWS

  3. Đếm số lần xuất hiện của một chuỗi con trong một chuỗi trong PostgreSQL

  4. Những vật thể lớn đáng sợ đó

  5. Cách nhanh chóng để khám phá số hàng của một bảng trong PostgreSQL