SQLalchemy rowcount luôn là -1 cho các câu lệnh

Nov 16 2020

Tôi đang chơi với SQLalchemy và Microsoft SQL Server để tìm hiểu các chức năng thì tôi bắt gặp một hành vi lạ. Tôi đã được dạy rằng thuộc tính rowcount trên đối tượng proxy kết quả sẽ cho biết có bao nhiêu hàng được thực hiện bằng cách thực thi một câu lệnh. Tuy nhiên, khi tôi chọn hoặc chèn một hoặc nhiều hàng trong cơ sở dữ liệu thử nghiệm của mình, tôi luôn nhận được -1. Làm thế nào điều này có thể được và làm thế nào tôi có thể sửa chữa điều này để phản ánh thực tế?

connection = engine.connect()
metadata = MetaData()

# Ex1: select statement for all values
student = Table('student', metadata, autoload=True, autoload_with=engine)
stmt = select([student])
result_proxy = connection.execute(stmt)
results = result_proxy.fetchall()
print(result_proxy.rowcount)

# Ex2: inserting single values
stmt = insert(student).values(firstname='Severus', lastname='Snape')
result_proxy = connection.execute(stmt)
print(result_proxy.rowcout)
 
# Ex3: inserting multiple values 
stmt = insert(student)
values_list = [{'firstname': 'Rubius', 'lastname': 'Hagrid'},
               {'firstname': 'Minerva', 'lastname': 'McGonogall'}]
result_proxy = connection.execute(stmt, values_list)
print(result_proxy.rowcount)

Hàm in cho mỗi khối chạy mã ví dụ riêng biệt sẽ in ra -1. Ex1 tìm nạp thành công tất cả các hàng và cả hai câu lệnh chèn đều ghi thành công dữ liệu vào cơ sở dữ liệu.

Theo vấn đề sau, thuộc tính rowcount không phải lúc nào cũng đáng tin cậy. Điều đó có đúng ở đây không? Và khi nào, tôi có thể bù trừ bằng câu lệnh Count trong giao dịch SQLalcehmy khi nào? PDO :: rowCount () trả về -1

Trả lời

1 GordThompson Nov 19 2020 at 02:46

Hàng đơn INSERT … VALUES ( … )là không quan trọng: Nếu câu lệnh thành công thì một hàng bị ảnh hưởng và nếu không thành công (tạo ra lỗi) thì không hàng nào bị ảnh hưởng.

Đối với nhiều hàng, INSERTchỉ cần thực hiện nó bên trong một giao dịch và khôi phục nếu xảy ra lỗi. Khi đó, số hàng bị ảnh hưởng sẽ bằng 0 hoặc len(values_list).

Để có được số hàng mà một SELECT sẽ trả về, hãy bọc truy vấn chọn trong một SELECT count(*)truy vấn và chạy truy vấn đó trước, ví dụ:

select_stmt = sa.select([Parent])
count_stmt = sa.select([sa.func.count(sa.text("*"))]).select_from(
    select_stmt.alias("s")
)
with engine.connect() as conn:
    conn.execution_options(isolation_level="SERIALIZABLE")
    rows_found = conn.execute(count_stmt).scalar()
    print(f"{rows_found} row(s) found")
    results = conn.execute(select_stmt).fetchall()
for item in results:
    print(item.id)