2010-05-30 16 views
16

no puedo encontrar la manera de configurar AUTO_INCREMENT en una columna único usando sqlalchemy 0.6.0 con MySQL 5.Establecer AUTO_INCREMENT utilizando SqlAlchemy con MySQL en Columnas con claves no primarias?

Sé que esto se puede hacer de MySQL, pero no quiero tener que distribuir adicional. scripts sql para configurar las bases de datos para mi aplicación. Quiero que SqlAlchemy construya el esquema desde dentro de Python.

Por lo que he encontrado hasta el momento, hay dos maneras en que una columna puede convertirse en una columna de tipo de incremento automático en sqlalchemy:

  1. Es la primera columna de sqlalchemy.types.Integer en la tabla que tiene primary_key=True y no tiene autoincrement=False establecido en su definición.
    • Con MSSQL esto agrega una propiedad INDEX(m,n) a la columna.
    • Con Postgres esto hace que se use el tipo de columna SERIAL.
    • Con MySQL agrega la propiedad AUTO_INCREMENT a la columna.
  2. Es una columna sqlalchemy.types.Integer y se crea una instancia con un objeto sqlalchemy.schema.Sequence como argumento.
    • Con MSSQL esto agrega una propiedad INDEX(m,n) a la columna.
    • Con Postgres esto hace que se use el tipo de columna SERIAL.
    • Con MySQL esto parece ser ignorado.

Así que no puedo utilizar # 1 porque la columna quiero auto_increment no está en la clave principal (ni debe ser). Y no puedo usar el n. ° 2 porque no funciona con MySQL.

Básicamente, mi código para definir la tabla tiene el siguiente aspecto:

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) 

y produce este SQL para crear la tabla:

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

¿Qué puedo hacer para conseguir que se produzca la siguiendo 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

Hasta ahora nunca han logrado hacer esto incluso directamente en MySQL, porque nunca he intentado marcar explícitamente el campo auto-incrementa clave no primaria como único. Gracias por eso. – newtover

Respuesta

4

Usted puede estar interesado en I need to auto_increment a field in MySQL that is not primary key

No estoy familiarizado con sqlalchemy, pero sí sé esto se puede lograr en MySQL. Primero debe definir la columna id como PRIMARY KEY y configurarla AUTO_INCREMENT. Entonces puede ALTER TABLE y DROP PRIMARY KEY, reemplazándolo con un ADD UNIQUE KEY. Esto conservará la funcionalidad AUTO_INCREMENT en esa columna. A continuación, puede crear el PRIMARY KEY en las otras columnas.

Para romper hacia abajo, el primer paso es la creación de la tabla de esta manera:

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

Siguiente modificar la clave id:

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

Por último, añadir su PRIMARY KEY en las otras columnas:

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

Gracias por su contribución, Dustin. Parece que si voy a hacerlo ejecutando ALTER TABLE, debería poder hacerlo guardando todo tal como está y ejecutando una sola persona "ALTER TABLE CHANGE ID id INTEGER NOT NULL AUTO_INCREMENT;". Volveré a publicar cuando descubra cómo hacerlo en Python. –

+0

Genial, me encantaría escuchar sus comentarios sobre si este enfoque funciona para usted con sqlalchemy. – defines

4

Extracto de http://www.mail-archive.com/[email protected]/msg19744.html

Su mejor opción por ahora es la emisión de un ALTER TABLE que se aplica la AUTO_INCREMENT, si MySQL soporta eso.

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

Es posible que desee enganchar esa declaración en la máquina de creación de tabla para que se ejecute en el momento correcto. Consulte http://stackoverflow.com/questions/12039046/in-sqlalchemy-how-do-i-define-an-event-to-fire-ddl-using-declarative-syntax para ver un ejemplo. –

+0

'execute_at' está en desuso desde v0.7. ver http://docs.sqlalchemy.org/en/latest/core/ddl.html#sqlalchemy.schema.DDLElement.execute_at –

Cuestiones relacionadas