2010-05-30 40 views
16

Tôi không thể tìm ra cách đặt AUTO_INCREMENT trên cột UNIQUE bằng cách sử dụng SqlAlchemy 0.6.0 với MySQL 5.Đặt AUTO_INCREMENT bằng cách sử dụng SqlAlchemy với MySQL trên Cột với các khóa không phải là chính?

Tôi biết điều này có thể được thực hiện trong MySQL, nhưng tôi không muốn phân phối thêm. sql script để thiết lập cơ sở dữ liệu cho ứng dụng của tôi. Tôi muốn SqlAlchemy xây dựng lược đồ từ bên trong Python.

Theo như tôi đã tìm thấy cho đến nay, có hai cách mà một cột có thể trở thành một loại cột tự động incrementing trong SQLAlchemy:

  1. Đây là sqlalchemy.types.Integer cột đầu tiên trong bảng có primary_key=True và không có autoincrement=False được đặt trong định nghĩa của nó.
    • Với MSSQL, điều này thêm một thuộc tính INDEX(m,n) vào cột.
    • Với Postgres, điều này khiến cho loại cột SERIAL được sử dụng.
    • Với MySQL thêm thuộc tính AUTO_INCREMENT vào cột.
  2. Đây là cột sqlalchemy.types.Integer và được khởi tạo với đối tượng sqlalchemy.schema.Sequence làm đối số.
    • Với MSSQL, điều này thêm một thuộc tính INDEX(m,n) vào cột.
    • Với Postgres, điều này khiến cho loại cột SERIAL được sử dụng.
    • Với MySQL, điều này dường như bị bỏ qua.

Vì vậy, tôi không thể sử dụng # 1 vì cột Tôi muốn auto_increment không nằm trong khóa chính (và cũng không cần). Và tôi không thể sử dụng # 2 vì nó không hoạt động với MySQL.

Về cơ bản, mã của tôi để xác định bảng trông giống như sau:

from sqlalchemy import Column 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.schema import Sequence 
from sqlalchemy.types import Integer, Unicode 
Base = declarative_base() 

class Person(Base): 
    __tablename__ = "person" 
    id = Column(Integer, nullable=False, unique=True) 
    first_name = Column(Unicode(100), nullable=False, primary_key=True) 
    last_name = Column(Unicode(100), nullable=False, primary_key=True) 

Và sản xuất SQL này để tạo bảng:

CREATE TABLE person (
    id INTEGER NOT NULL, 
    first_name VARCHAR(100) NOT NULL, 
    last_name VARCHAR(100) NOT NULL, 
    PRIMARY KEY (first_name, last_name), 
    UNIQUE (id) 
) 

tôi có thể làm gì để có được nó để sản xuất sau SQL?

CREATE TABLE person (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    first_name VARCHAR(100) NOT NULL, 
    last_name VARCHAR(100) NOT NULL, 
    PRIMARY KEY (first_name, last_name), 
    UNIQUE (id) 
) 
+0

Cho đến bây giờ tôi chưa bao giờ được quản lý để làm điều này thậm chí trực tiếp trong MySQL, bởi vì tôi không bao giờ cố gắng để đánh dấu một cách rõ ràng lĩnh vực tự động tăng lên chính phi chính như UNIQUE. Cảm ơn vì điều đó. – newtover

Trả lời

4

Bạn có thể quan tâm I need to auto_increment a field in MySQL that is not primary key

Tôi không quen thuộc với SQLAlchemy, nhưng tôi biết điều này có thể được thực hiện trong MySQL. Trước tiên, bạn phải xác định cột id làm PRIMARY KEY và đặt nó AUTO_INCREMENT. Sau đó, bạn có thể ALTER TABLEDROP PRIMARY KEY, thay thế bằng ADD UNIQUE KEY. Điều này sẽ duy trì chức năng AUTO_INCREMENT trên cột đó. Sau đó, bạn có thể tạo các PRIMARY KEY trên các cột khác.

Để phá vỡ nó xuống, bước đầu tiên của bạn là tạo ra bàn thusly:

CREATE TABLE person (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    first_name VARCHAR(100) NOT NULL, 
    last_name VARCHAR(100) NOT NULL, 
    PRIMARY KEY (id) 
); 

Tiếp theo thay đổi id chính:

ALTER TABLE person DROP PRIMARY KEY, ADD UNIQUE KEY(id); 

Cuối cùng, thêm PRIMARY KEY của bạn trên các cột khác:

ALTER TABLE person ADD PRIMARY KEY(first_name, last_name); 
+0

Cảm ơn bạn đã nhập liệu, Dustin. Có vẻ như nếu tôi sẽ làm điều đó bằng cách thực hiện một ALTER TABLE, tôi sẽ có thể làm điều đó bằng cách giữ mọi thứ như hiện tại và thực hiện một "ALTER TABLE person CHANGE id id INTEGER NOT NULL AUTO_INCREMENT;". Tôi sẽ đăng lại khi tôi tìm ra cách thực hiện điều này bằng Python. –

+0

Tuyệt vời, tôi rất thích nghe ý kiến ​​phản hồi của bạn về việc liệu phương pháp này có hiệu quả với bạn với sqlalchemy hay không. – defines

4

Trích từ http://www.mail-archive.com/[email protected]/msg19744.html

Đặt cược tốt nhất hiện tại của bạn là phát hành ALTER TABLE áp dụng AUTO_INCREMENT, nếu MySQL hỗ trợ điều đó.

from sqlalchemy.schema import DDL 
DDL("ALTER TABLE person ...", on='mysql').execute_at('after-create', 
    person_table)[..] 
+0

Bạn có thể muốn móc câu lệnh đó vào machienry tạo bảng để nó được thực thi vào đúng thời điểm. Xem http://stackoverflow.com/questions/12039046/in-sqlalchemy-how-do-i-define-an-event-to-fire-ddl-using-declarative-syntax để biết ví dụ. –

+0

'execute_at' không được chấp nhận vì v0.7. xem http://docs.sqlalchemy.org/en/latest/core/ddl.html#sqlalchemy.schema.DDLElement.execute_at –

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