2012-05-08 7 views
19

Das autoincrement Argument in SQLAlchemy scheint nur True und False zu sein, aber ich will aid = 1001 den vordefinierten Wert setzen, aid = 1002 die über Autoinkrement, wenn der nächste Einsatz erfolgt.SQLAlchemy Einstellung AutoIncrement Startwert

In SQL kann wie geändert werden:

ALTER TABLE article AUTO_INCREMENT = 1001; 

ich MySQL bin mit und ich habe versucht folgend, aber es funktioniert nicht:

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) 

Also, wie kann ich Das? Danke im Voraus!

Antwort

16

Sie können dies erreichen, indem Sie DDLEvents verwenden. Dadurch können Sie zusätzliche SQL-Anweisungen ausführen, unmittelbar nachdem CREATE TABLE ausgeführt wurde. Schauen Sie sich die Beispiele in den Link, aber ich vermute, Ihr Code wie folgt aussehen unten:

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

Es funktioniert! Vielen Dank. – Gorthon

+1

Gibt es eine Möglichkeit zu verhindern, dass dies abhängig vom Datenbankanbieter ausgeführt wird? Der ALTER ... AUTO_INCREMENT funktioniert gut für MySQL (und die meisten anderen dbs, denke ich), jedoch wird diese SQL anscheinend für SQLITE nicht unterstützt. Die nächste Problemumgehung, die ich finden könnte, ist ein Einfügen/Löschen: http://stackoverflow.com/questions/692856/set-start-value-for-autoincrement-in-sqlite – coderfi

+1

Beantwortete meine eigene Frage. Durch den Code stochernd, fand ich die Lösung, die dokumentiert wird durch: http://docs.sqlalchemy.org/en/rel_0_8/core/ddl.html#sqlalchemy.schema.DDLElement.execute_if Das oben könnte neu geschrieben werden als event.listen ( Artikel .__ table__, "after_create" DDL ("TABLE ALTES% (Tabelle) s AUTO_INCREMENT = 1001;") execute_if (Dialekt = ('postgresql', 'mysql')) .) was mich um das SQLite-Problem bringt. – coderfi

14

Nach the docs:

Autoinkrement - Dieser Flag auf Falsch gesetzt werden, eine ganze Zahl Primärschlüsselspalt, um anzuzeigen, die nicht in Betracht gezogen werden sollten, den „Autoinkrement“ -Spalte sein, dass der ganze Zahl Primärschlüssel Spalte, die implizit Werte für INSERT generiert und deren Wert normalerweise über das DBAPI-Attribut cursor.lastrowid zurückgegeben wird. Standardmäßig wird True verwendet, um den allgemeinen Anwendungsfall einer Tabelle mit einer einzelnen Primärschlüsselspalte zu erfüllen.

So autoincrement ist nur ein Flag SQLAlchemy wissen zu lassen, ob es der Primärschlüssel ist Sie erhöhen möchten.

Was Sie versuchen zu tun ist, eine benutzerdefinierte autoincrement erstellen Sequenz.

So, Ihr Beispiel, ich denken, sollte in etwa so aussehen:

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) 

Hinweis, ich weiß nicht, ob Sie PostgreSQL oder nicht verwenden, so sollten Sie Kenntnis von der following machen wenn Sie:

Das Sequence-Objekt implementiert auch spezielle Funktionalität PostgreSQLs SERIAL Datentyp anzupassen. Der Typ SERIAL in PG erzeugt automatisch eine Sequenz, die bei Inserts implizit verwendet wird. Dies bedeutet, dass, wenn ein Tabellenobjekt eine Sequenz in seiner Primärschlüsselspalte definiert, so dass es mit Oracle und Firebird zusammenarbeitet, die Sequenz der "impliziten" Sequenz im Wege steht, die PG normalerweise verwenden würde. Fügen Sie für diesen Anwendungsfall das Flag optional = True zum Sequence-Objekt hinzu - dies bedeutet, dass die Sequence nur verwendet werden sollte, wenn die Datenbank keine andere Option zum Generieren von Primärschlüssel-IDs bietet.

+0

Ich benutze MySQL. Gemäß der Dokumentation: Es hat nur Auswirkungen auf Datenbanken, die explizite Unterstützung für Sequenzen haben, die derzeit enthält ** Postgresql **, ** Oracle ** und ** Firebird **. Ich habe Ihren Code versucht, aber es funktioniert immer noch nicht. – Gorthon

+0

Ahhh, mein Schlechter (ich benutze PG wann immer ich sehen kann). In diesem Fall würde ich einen Höhepunkt bei @ van's Antwort oben nehmen! – Edwardr

+0

Entschuldigung für mein schlechtes Englisch (Ich weiß nicht, was "mein schlechtes" und "nimm einen Höhepunkt" bedeutet) Tatsächlich ist @ van's Antwort später als deine. Danke sehr sehr! – Gorthon

1

konnte ich die anderen Antworten nicht erhalten mit mysql und arbeiten flaschen wandern, so habe ich die folgenden innerhalb eines Migrationsdatei

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

Seien Sie gewarnt, dass, wenn Sie Ihre Migration Dateien regeneriert diese überschrieben werden.