2012-05-08 18 views
19

L'argomento autoincrement in SQLAlchemy sembra essere solo True e False, ma voglio impostare il valore predefinito aid = 1001, la via autoincrement aid = 1002 quando l'inserto successivo è fatto.Impostazione SQLAlchemy AutoIncrement iniziare valore

In SQL, può essere modificata come:

ALTER TABLE article AUTO_INCREMENT = 1001; 

sto usando MySQL e ho provato dopo, ma non funziona:

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) 

Così, come posso ottenere quella? Grazie in anticipo!

risposta

16

È possibile ottenere questo utilizzando DDLEvents. Ciò consentirà di eseguire istruzioni SQL aggiuntive subito dopo l'esecuzione dello CREATE TABLE. Un'occhiata agli esempi nel link, ma sto indovinando il vostro codice sarà simile al di sotto:

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

Funziona! Grazie mille. – Gorthon

+1

C'è un modo per escludere questo da essere eseguito a seconda del provider db? L'ALTER ... AUTO_INCREMENT funziona bene per MySQL (e la maggior parte degli altri dbs penso), tuttavia questo SQL apparentemente non è supportato da SQLITE. Il rimedio più vicino che ho trovato è quello di fare un insert/delete: http://stackoverflow.com/questions/692856/set-start-value-for-autoincrement-in-sqlite – coderfi

+1

Ho risposto alla mia stessa domanda. Sfogliando il codice, ho trovato la soluzione, che è documentata da: http://docs.sqlalchemy.org/en/rel_0_8/core/ddl.html#sqlalchemy.schema.DDLElement.execute_if Quanto sopra potrebbe essere riscritto come event.listen ( articolo .__ table__, "after_create", DDL ("ALTER tABLE% (tabella) s AUTO_INCREMENT = 1001;") execute_if (dialetto = ('PostgreSQL', 'mysql')) .) che mi porta in giro per il problema sqlite. – coderfi

14

Secondo the docs:

autoincrement - Questo flag può essere impostata su False per indicare una colonna di chiave primaria intero che non dovrebbe essere considerata la colonna “autoincrement”, che è la chiave primaria intero colonna che genera implicitamente valori su INSERT e il cui valore viene in genere restituito tramite l'attributo cursor.lastrowid DBAPI. Il valore predefinito è True per soddisfare il caso di uso comune di una tabella con una singola colonna di chiave primaria intera.

Quindi, autoincrement è solo una bandiera per far SQLAlchemy so se è la chiave primaria che si desidera incrementare.

Quello che si sta tentando di fare è creare una sequenza di autoincremento personalizzata sequenza.

Quindi, il tuo esempio, io penso , dovrebbe essere simile:

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) 

nota, non so se si sta utilizzando PostgreSQL o no, così si dovrebbe prendere nota della following in caso affermativo:

L'oggetto Sequenza implementa anche funzionalità speciali per il tipo di dati SERIAL di Postgresql. Il tipo SERIAL in PG genera automaticamente una sequenza che viene utilizzata implicitamente durante gli inserimenti. Ciò significa che se un oggetto Table definisce una Sequenza sulla sua colonna di chiave primaria in modo che funzioni con Oracle e Firebird, la Sequenza interferirebbe con la sequenza "implicita" che il PG normalmente userebbe. Per questo caso d'uso, aggiungi il flag opzionale = True all'oggetto Sequence - questo indica che la Sequenza dovrebbe essere utilizzata solo se il database non fornisce altre opzioni per la generazione di identificatori di chiavi primarie.

+0

Sto usando MySQL. Secondo i documenti: Ha solo un effetto sui database che hanno il supporto esplicito per le sequenze, che attualmente include ** Postgresql **, ** Oracle ** e ** Firebird **. Ho provato il codice, ma ancora non funziona. – Gorthon

+0

Ahhh, mio ​​male (uso PG ogni volta che riesco a vedere). In tal caso, darei un picco alla risposta di @ van sopra! – Edwardr

+0

Scusate per il mio scarso inglese. (Non conosco il significato di "my bad" e "prendi un picco") Infatti, la risposta di @ van è successiva alla vostra. Grazie mille! – Gorthon

1

non ho potuto ottenere le altre risposte a lavorare con mysql e pallone-migrate così ho fatto la seguente all'interno di un file di migrazione.

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

Si noti che se si sono rigenerati i file di migrazione questo verrà sovrascritto.

Problemi correlati