2011-12-21 38 views
6

Tôi vừa chạy qua một vấn đề khá khó hiểu, và sau khi kiểm tra tôi đã thấy rằng NONE của các câu trả lời có sẵn là đủ.Nhận giá trị chèn vào cuối cùng từ MySQL bằng cách sử dụng SQLAlchemy

Tôi đã thấy các đề xuất khác nhau nhưng dường như không có khả năng trả về giá trị được chèn cuối cùng cho trường auto_increment trong MySQL.

Tôi đã xem các ví dụ đề cập đến việc sử dụng session.flush() để thêm bản ghi và sau đó truy lục id. Tuy nhiên điều đó dường như luôn trở 0.

Tôi cũng đã thấy ví dụ đề cập đến việc sử dụng các session.refresh() nhưng điều đó đặt ra các lỗi sau: InvalidRequestError: Không thể làm mới dụ ''

Những gì tôi cố gắng để làm dường như điên rồ đơn giản nhưng tôi dường như không thể tìm ra bí mật.

Tôi đang sử dụng phương pháp khai báo.

Do đó, mã của tôi trông giống như sau:

class Foo(Base): 
    __tablename__ = 'tblfoo' 
    __table_args__ = {'mysql_engine':'InnoDB'} 

    ModelID = Column(INTEGER(unsigned=True), default=0, primary_key=True, autoincrement=True) 
    ModelName = Column(Unicode(255), nullable=True, index=True) 
    ModelMemo = Column(Unicode(255), nullable=True) 

f = Foo(ModelName='Bar', ModelMemo='Foo') 
session.add(f) 
session.flush() 

Tại thời điểm này, đối tượng f đã được đẩy lên DB, và đã tự động gán độc đáo id khóa chính. Tuy nhiên, tôi không thể tìm cách để có được giá trị để sử dụng trong một số hoạt động bổ sung. Tôi muốn làm như sau:

my_new_id = f.ModelID

Tôi biết tôi chỉ đơn giản là có thể thực hiện một truy vấn để tra cứu các ModelID dựa trên các thông số khác nhưng tôi không muốn nếu có thể.

Tôi sẽ đánh giá cao mọi thông tin chi tiết về giải pháp cho vấn đề này.

Cảm ơn bạn đã trợ giúp trước.

Trả lời

9

Vấn đề là bạn đang đặt defaul để tăng tự động. Vì vậy, khi nó chạy chèn vào truy vấn các bản ghi của máy chủ là

2011-12-21 13:44:26,561 INFO sqlalchemy.engine.base.Engine.0x...1150 INSERT INTO tblfoo (`ModelID`, `ModelName`, `ModelMemo`) VALUES (%s, %s, %s) 
2011-12-21 13:44:26,561 INFO sqlalchemy.engine.base.Engine.0x...1150 (0, 'Bar', 'Foo') 
ID : 0 

Vì vậy, đầu ra là 0 mà là giá trị mặc định và được thông qua bởi vì bạn đang thiết lập giá trị mặc định cho autoincrement cột.

Nếu tôi chạy cùng mã mà không cần default thì nó sẽ cung cấp kết quả chính xác.

Vui lòng thử mã này

from sqlalchemy import create_engine 
engine = create_engine('mysql://test:[email protected]/test1', echo=True) 

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 

from sqlalchemy.orm import sessionmaker 
Session = sessionmaker(bind=engine) 

session = Session() 

from sqlalchemy import Column, Integer, Unicode 

class Foo(Base): 
    __tablename__ = 'tblfoo' 
    __table_args__ = {'mysql_engine':'InnoDB'} 

    ModelID = Column(Integer, primary_key=True, autoincrement=True) 
    ModelName = Column(Unicode(255), nullable=True, index=True) 
    ModelMemo = Column(Unicode(255), nullable=True) 

Base.metadata.create_all(engine) 

f = Foo(ModelName='Bar', ModelMemo='Foo') 
session.add(f) 
session.flush() 

print "ID :", f.ModelID 
+1

Bắt tốt, không nhận thấy mặc định = 0. –

+1

Nhật ký máy chủ sẽ luôn hoạt động để tìm ra vấn đề :) – Nilesh

+1

Ugh ... vâng, bắt thú vị. Đầu của tôi là trong thế giới SQL, nơi một giá trị mặc định được yêu cầu cho một trường khóa chính khi bạn tạo bảng. Cảm ơn bạn đã tìm thấy. – PlaidFan

1

Hãy thử sử dụng session.commit() thay vì session.flush(). Sau đó, bạn có thể sử dụng f.ModelID.

+0

Tôi đã thử nó sau khi cả hai tuôn và cam kết nhưng không nhận được các lỗi sau đây: AttributeError: đối tượng 'Foo' không có thuộc tính 'id' – PlaidFan

+0

Xin lỗi, cập nhật câu trả lời để sử dụng ModelID như bạn đã sử dụng vào khai báo lược đồ của mình. Tuy nhiên, có lẽ bạn nên sử dụng 'id' thay vì' ModelID'. –

+0

Đáng buồn thay, tôi đã thử cách tiếp cận đó nhiều cách và tiếp tục nhận được lỗi sau: ObjectDeletedError: Instance '' đã bị xóa. – PlaidFan

1

Không chắc chắn tại sao câu trả lời làm việc gắn cờ cho bạn. Nhưng trong trường hợp của tôi, điều đó không thực sự chèn hàng vào bảng. Tôi cần gọi số commit() cuối cùng.

Vì vậy, một vài dòng cuối cùng của mã là:

f = Foo(ModelName='Bar', ModelMemo='Foo') 
session.add(f) 
session.flush() 

print "ID:", f.ModelID 

session.commit() 
Các vấn đề liên quan