2012-05-08 32 views
19

Các autoincrement luận trong SQLAlchemy có vẻ là chỉ TrueFalse, nhưng tôi muốn thiết lập được xác định trước giá trị aid = 1001, thông qua autoincrement aid = 1002 khi chèn tiếp theo được thực hiện.Thiết SQLAlchemy autoincrement giá trị đầu

Trong SQL, có thể được thay đổi như sau:

ALTER TABLE article AUTO_INCREMENT = 1001; 

Tôi đang sử dụng MySQL và tôi đã cố gắng sau đó, nhưng nó không hoạt động:

from sqlalchemy.ext.declarative import declarative_base 
Base = declarative_base() 
class Article(Base): 
    __tablename__ = 'article' 
    aid = Column(INTEGER(unsigned=True, zerofill=True), 
       autoincrement=1001, primary_key=True) 

Vì vậy, làm thế nào tôi có thể nhận được cái đó? Cảm ơn trước!

Trả lời

16

Bạn có thể đạt được điều này bằng cách sử dụng DDLEvents. Điều này sẽ cho phép bạn chạy các câu lệnh SQL bổ sung ngay sau khi chạy CREATE TABLE. Nhìn vào các ví dụ trong các liên kết, nhưng tôi đoán mã của bạn sẽ trông giống như dưới đây:

from sqlalchemy import event 
from sqlalchemy import DDL 
event.listen(
    Article.__table__, 
    "after_create", 
    DDL("ALTER TABLE %(table)s AUTO_INCREMENT = 1001;") 
) 
+0

Nó hoạt động! Cảm ơn rất nhiều. – Gorthon

+1

Có cách nào để loại trừ điều này khỏi việc thực hiện tùy thuộc vào nhà cung cấp db không? ALTER ... AUTO_INCREMENT hoạt động tốt cho MySQL (và hầu hết các dbs khác tôi nghĩ), tuy nhiên, SQL này dường như không được hỗ trợ cho SQLITE. Cách giải quyết gần nhất tôi có thể tìm thấy là chèn/xóa: http://stackoverflow.com/questions/692856/set-start-value-for-autoincrement-in-sqlite – coderfi

+1

Đã trả lời câu hỏi của riêng tôi. Poking thông qua các mã, tôi tìm thấy các giải pháp, được tài liệu bởi: http://docs.sqlalchemy.org/en/rel_0_8/core/ddl.html#sqlalchemy.schema.DDLElement.execute_if Ở trên có thể được viết lại như event.listen ( Điều .__ table__, "after_create", DDL ("ALTER tABLE% (bảng) s AUTO_INCREMENT = 1001;") execute_if (phương ngữ = ('postgresql', 'mysql')) .) giúp tôi giải quyết vấn đề sqlite. – coderfi

14

Theo the docs:

autoincrement - Cờ này có thể được thiết lập để False để chỉ một cột khóa chính số nguyên không nên được coi là “autoincrement” cột, đó là chìa khóa chính số nguyên cột tạo ra các giá trị ngầm khi INSERT và giá trị của nó thường được trả về thông qua thuộc tính DBAPI cursor.lastrowid. Nó mặc định là True để đáp ứng trường hợp sử dụng chung của một bảng với một cột khóa nguyên duy nhất.

Vì vậy, autoincrement chỉ là cờ để cho phép SQLAlchemy biết liệu đó có phải là khóa chính bạn muốn tăng hay không.

Điều bạn đang cố làm là tạo tự động tùy chỉnh trình tự.

Vì vậy, ví dụ của bạn, tôi nghĩ , nên giống như thế:

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.schema import Sequence 

Base = declarative_base() 

class Article(Base): 
    __tablename__ = 'article' 
    aid = Column(INTEGER(unsigned=True, zerofill=True), 
       Sequence('article_aid_seq', start=1001, increment=1), 
       primary_key=True) 

Lưu ý, tôi không biết liệu bạn đang sử dụng PostgreSQL hay không, vì vậy bạn nên lưu ý những following nếu bạn là:

Đối tượng Sequence cũng thực hiện chức năng đặc biệt để phù hợp với kiểu dữ liệu SERIALql SERIAL. Loại SERIAL trong PG sẽ tự động tạo ra một chuỗi được sử dụng ngầm trong quá trình chèn. Điều này có nghĩa là nếu một đối tượng Table định nghĩa một Sequence trên cột khóa chính của nó sao cho nó hoạt động với Oracle và Firebird, thì Sequence sẽ cản trở trình tự "ngầm định" mà PG thường sử dụng. Đối với trường hợp sử dụng này, thêm cờ tùy chọn = True cho đối tượng Sequence - điều này chỉ ra rằng Sequence chỉ nên được sử dụng nếu cơ sở dữ liệu không cung cấp tùy chọn nào khác để tạo các mã định danh khóa chính.

+0

Tôi đang sử dụng MySQL. Theo tài liệu: Nó chỉ có tác dụng trên cơ sở dữ liệu có hỗ trợ rõ ràng cho chuỗi, hiện tại bao gồm ** Postgresql **, ** Oracle ** và ** Firebird **. Tôi đã thử mã của bạn, nhưng mã vẫn không hoạt động. – Gorthon

+0

Ahhh, tệ của tôi (tôi sử dụng PG bất cứ khi nào tôi có thể thấy). Trong trường hợp đó, tôi sẽ đạt đỉnh điểm tại câu trả lời của @ van ở trên! – Edwardr

+0

Xin lỗi vì tiếng Anh nghèo nàn của tôi (Tôi không biết ý nghĩa của ‘my bad' và' take a peak at') Trên thực tế, câu trả lời của @ van muộn hơn của bạn. Cảm ơn rất nhiều! – Gorthon

1

tôi không thể có được câu trả lời khác để làm việc sử dụng mysql và bình-di chuyển vì vậy tôi đã làm như sau trong một tệp di chuyển.

from app import db 
db.engine.execute("ALTER TABLE myDB.myTable AUTO_INCREMENT = 2000;") 

Được cảnh báo rằng nếu bạn tạo lại tệp di chuyển của mình, tệp này sẽ bị ghi đè.

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