TRÊN CẬP NHẬT KHÓA DUPLICATE
đăng phiên bản 1.2 cho MySQL
Chức năng này hiện được tích hợp vào SQLAlchemy chỉ dành cho MySQL. Câu trả lời của somada141 dưới đây có giải pháp tốt nhất: https://stackoverflow.com/a/48373874/319066
TRÊN CẬP NHẬT KHÓA DUPLICATE
trong câu lệnh SQL
Nếu bạn muốn SQL được tạo thực sự bao gồm TRÊN CẬP NHẬT KHÓA DUPLICATE
, cách đơn giản nhất là sử dụng @compiles
người trang trí.
Mã (được liên kết từ một chuỗi tốt về chủ đề trên reddit ) ví dụ có thể được tìm thấy trên github :
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def append_string(insert, compiler, **kw):
s = compiler.visit_insert(insert, **kw)
if 'append_string' in insert.kwargs:
return s + " " + insert.kwargs['append_string']
return s
my_connection.execute(my_table.insert(append_string = 'ON DUPLICATE KEY UPDATE foo=foo'), my_values)
Nhưng lưu ý rằng trong cách tiếp cận này, bạn phải tạo append_string theo cách thủ công. Bạn có thể thay đổi hàm append_string để nó tự động thay đổi chuỗi chèn thành một chuỗi chèn có chuỗi 'ON DUPLICATE KEY UPDATE', nhưng tôi sẽ không làm điều đó ở đây do lười biếng.
TRÊN CẬP NHẬT KHÓA DUPLICATE
chức năng trong ORM
SQLAlchemy không cung cấp giao diện để TRÊN CẬP NHẬT KHÓA DUPLICATE
hoặc MERGE
hoặc bất kỳ chức năng tương tự nào khác trong lớp ORM của nó. Tuy nhiên, nó có session.merge ()
chức năng có thể sao chép chức năng chỉ khi khóa được đề cập là khóa chính .
session.merge (ModelObject)
trước tiên hãy kiểm tra xem một hàng có cùng giá trị khóa chính tồn tại bằng cách gửi SELECT
truy vấn (hoặc bằng cách tra cứu cục bộ). Nếu có, nó sẽ đặt một cờ ở đâu đó cho biết rằng ModelObject đã có trong cơ sở dữ liệu và SQLAlchemy nên sử dụng UPDATE
truy vấn. Lưu ý rằng hợp nhất phức tạp hơn một chút so với cách này, nhưng nó sao chép tốt chức năng với các khóa chính.
Nhưng nếu bạn muốn TRÊN CẬP NHẬT KHÓA DUPLICATE
chức năng với một khóa không phải chính (ví dụ:một khóa duy nhất khác)? Thật không may, SQLAlchemy không có bất kỳ chức năng nào như vậy. Thay vào đó, bạn phải tạo thứ gì đó giống với get_or_create ()
của Django . Một câu trả lời StackOverflow khác đề cập đến vấn đề này
và tôi sẽ chỉ dán một phiên bản đã sửa đổi, đang hoạt động của nó vào đây để thuận tiện.
def get_or_create(session, model, defaults=None, **kwargs):
instance = session.query(model).filter_by(**kwargs).first()
if instance:
return instance
else:
params = dict((k, v) for k, v in kwargs.iteritems() if not isinstance(v, ClauseElement))
if defaults:
params.update(defaults)
instance = model(**params)
return instance