2010-05-30 6 views
16

Io non riesco a capire come impostare AUTO_INCREMENT su una colonna univoca utilizzando SQLAlchemy 0.6.0 con MySQL 5.Impostare AUTO_INCREMENT utilizzando SqlAlchemy con MySQL su colonne con chiavi non principali?

So che questo può essere fatto in MySQL, ma io non voglio avere a distribuire in più. script sql per configurare i database per la mia applicazione. Voglio che SqlAlchemy costruisca lo schema da Python.

Per quanto ho trovato finora, ci sono due modi che una colonna può diventare una colonna di tipo incremento automatico in SQLAlchemy:

  1. E 'la prima sqlalchemy.types.Integer colonna della tabella che ha primary_key=True e non ha autoincrement=False impostato nella sua definizione.
    • Con MSSQL questo aggiunge una proprietà INDEX(m,n) alla colonna.
    • Con Postgres viene utilizzato il tipo di colonna SERIAL.
    • Con MySQL aggiunge la proprietà AUTO_INCREMENT alla colonna.
  2. È una colonna sqlalchemy.types.Integer ed è un'istanza con un oggetto sqlalchemy.schema.Sequence come argomento.
    • Con MSSQL questo aggiunge una proprietà INDEX(m,n) alla colonna.
    • Con Postgres viene utilizzato il tipo di colonna SERIAL.
    • Con MySQL questo sembra essere ignorato.

Quindi non posso usare 1 # perché la colonna che voglio auto_increment non è nella chiave primaria (né deve essere). E non posso usare # 2 perché non funziona con MySQL.

Fondamentalmente, il mio codice per definire la tabella si presenta come la seguente:

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) 

e produce questo SQL per creare la tabella:

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

Che cosa posso fare per ottenerlo per produrre la seguendo 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

Fino ad ora non sono mai riuscito a farlo anche direttamente in MySQL, perché non ho mai cercato di marcare in modo esplicito il campo auto-increment chiave non primario come unica. Grazie per questo. – newtover

risposta

4

Potreste essere interessati a I need to auto_increment a field in MySQL that is not primary key

io non sono a conoscenza SQLAlchemy, ma so questo può essere compiuto in MySQL. È necessario innanzitutto definire la colonna id come PRIMARY KEY e impostarla su AUTO_INCREMENT. Quindi è possibile ALTER TABLE e DROP PRIMARY KEY, sostituendolo con un ADD UNIQUE KEY. Ciò manterrà la funzionalità AUTO_INCREMENT su quella colonna. È quindi possibile creare il PRIMARY KEY sulle altre colonne.

Per rompere il basso, il primo passo è quello di creare la tabella seguente modo:

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

Avanti modificare la chiave id:

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

Infine, aggiungere il PRIMARY KEY sulle altre colonne:

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

Grazie per il tuo contributo, Dustin. Sembra che se lo farò eseguendo un ALTER TABLE, dovrei essere in grado di farlo mantenendo tutto così com'è ed eseguendo un singolo "ALTER TABLE person CHANGE id id INTEGER NON NULL AUTO_INCREMENT;". Ti posterò quando capirò come farlo in Python. –

+0

Fantastico, mi piacerebbe sentire il tuo feedback sul fatto che questo approccio funzioni con sqlalchemy. – defines

4

Estratto da http://www.mail-archive.com/[email protected]/msg19744.html

La cosa migliore per ora è di emettere un ALTER TABLE che applica la AUTO_INCREMENT, se MySQL supporta questo.

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

Si potrebbe voler agganciare quella dichiarazione alla machieria di creazione della tabella in modo che venga eseguita al momento giusto. Vedi http://stackoverflow.com/questions/12039046/in-sqlalchemy-how-do-i-define-an-event-to-fire-ddl-using-declarative-syntax per un esempio. –

+0

'execute_at' è deprecato dalla v0.7. vedi http://docs.sqlalchemy.org/en/latest/core/ddl.html#sqlalchemy.schema.DDLElement.execute_at –