2010-05-30 8 views
16

Ich kann nicht herausfinden, wie AUTO_INCREMENT auf einer eindeutigen Spalte setzen mit sqlalchemy 0.6.0 mit MySQL 5.Setzen Sie AUTO_INCREMENT mit SqlAlchemy mit MySQL auf Spalten mit Nicht-Primärschlüsseln?

Ich weiß, das in MySQL getan werden kann, aber ich will nicht extra haben zu verteilen. SQL-Skripte, um die Datenbanken für meine Anwendung einzurichten. Ich möchte, dass SqlAlchemy das Schema in Python erstellt.

Was ich gefunden habe, so weit, gibt es zwei Möglichkeiten, dass eine Spalte ein automatischer Erhöhung Typ Spalte in sqlalchemy werden kann:

  1. Es ist die erste sqlalchemy.types.Integer Spalte in der Tabelle, die primary_key=True hat und hat in seiner Definition autoincrement=False nicht festgelegt.
    • Mit MSSQL dies fügt eine INDEX(m,n) Eigenschaft auf die Säule.
    • Bei Postgres wird der Spaltentyp SERIAL verwendet.
    • Mit MySQL fügt die Spalte die AUTO_INCREMENT-Eigenschaft hinzu.
  2. Es ist eine sqlalchemy.types.Integer Spalte, und ist mit einem sqlalchemy.schema.Sequence Objekt als Argument instanziiert.
    • Mit MSSQL fügt das eine Spalte INDEX(m,n) zu der Spalte hinzu.
    • Bei Postgres wird der Spaltentyp SERIAL verwendet.
    • Mit MySQL scheint dies ignoriert zu werden.

So kann ich nicht # 1 verwenden, da die Spalte I auto_increment wollen nicht im Primärschlüssel ist (noch sollte es sein). Und ich kann # 2 nicht verwenden, weil es nicht mit MySQL funktioniert.

Grundsätzlich mein Code die Tabelle zu definieren, sieht wie folgt aus:

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) 

und produziert diese SQL die Tabelle zu erstellen:

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) 
) 

Was kann ich es tun, um das zu produzieren folgenden 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

Bis jetzt habe ich noch nie so auch direkt zu tun in MySQL verwaltet, weil ich nie explizit versucht, das Nicht-Primärschlüssel automatisch inkrementierte Feld als UNIQUE markiert. Danke für das. – newtover

Antwort

4

Sie könnten in I need to auto_increment a field in MySQL that is not primary key

interessiert sein Ich bin nicht vertraut mit sqlalchemy, aber ich weiß, dass dies in MySQL erreicht werden kann. Sie müssen zuerst die Spalte id als PRIMARY KEY definieren und sie auf AUTO_INCREMENT setzen. Dann können Sie ALTER TABLE und DROP PRIMARY KEY ersetzen und durch ADD UNIQUE KEY ersetzen. Dadurch wird die AUTO_INCREMENT-Funktionalität für diese Spalte beibehalten. Sie können dann die PRIMARY KEY für die anderen Spalten erstellen.

es zu brechen, ist Ihr erster Schritt ist die Tabelle thusly zu erstellen:

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

Nächstes ändern Sie die id Schlüssel:

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

Schließlich fügen Sie Ihre PRIMARY KEY auf den anderen Spalten:

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

Danke für Ihre Eingabe, Dustin. Es sieht so aus, als wenn ich es tun würde, indem ich eine ALTER TABLE ausführe, sollte ich in der Lage sein, alles zu tun, wie es ist, und einen einzelnen "ALTER TABLE Person CHANGE id id INTEGER NOT NULL AUTO_INCREMENT;" auszuführen. Ich poste zurück, wenn ich herausfinde, wie man das in Python macht. –

+0

Toll, ich würde gerne Ihre Rückmeldung darüber hören, ob dieser Ansatz für Sie mit sqlalchemy funktioniert. – defines

4

Auszug aus http://www.mail-archive.com/[email protected]/msg19744.html

beste Wahl für Arbeit jetzt ist eine ALTER TABLE auszustellen, die die AUTO_INCREMENT gilt, wenn MySQL, dass unterstützt.

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

Sie könnten diese Anweisung in die Tabellenerstellungsmaschine einhängen, damit sie zur richtigen Zeit ausgeführt wird. Ein Beispiel finden Sie unter http://stackoverflow.com/questions/12039046/in-sqlalchemy-how-do-i-define-an-event-to-fire-ddl-using-declarative-syntax. –

+0

'execute_at' ist seit v0.7 veraltet. siehe http://docs.sqlalchemy.org/en/latest/core/ddl.html#sqlalchemy.schema.DDLElement.execute_at –

Verwandte Themen