2012-02-15 34 views
5

Estoy usando una base de datos existente hecha por un tercero con sqlalchemy. Sin embargo, tengo problemas ya que las tablas no tienen claves primarias, y lo que es peor, tienen elementos duplicados para cada fila, por lo que no puedo elegir una columna existente como clave principal. Las tablas tienen dos columnas: ambas tienen valores no únicos.Python sqlalchemy: tabla sin claves principales y valores duplicados?

Traté de mono-parche de la mesa según http://www.blog.pythonlibrary.org/2010/09/10/sqlalchemy-connecting-to-pre-existing-databases/ pero al parecer esto no funciona (ver más abajo)

Mi código actual es (MirnaTable es mi clase asignada, básicamente, sólo un esqueleto con nada más)

connection = create_engine("sqlite:///targets.sqlite") 
metadata = MetaData(bind=connection) 
db_table = Table("miranda", metadata, 
       Column("id", Integer, primary_key=True), 
       autoload=True) 
mapper(MirnaTable, db_table) 
Session = sessionmaker(connection) 
session = Session() 

Entonces trato, por ejemplo, la emisión de

all_records = session.query(MirnaTable).all() 

Y consigo

sqlalchemy.exc.OperationalError: (OperationalError) no such column: miranda.id 
u'SELECT miranda.gene_id AS miranda_gene_id, miranda."mature_miRNA" AS 
"miranda_mature_miRNA", miranda.id AS miranda_id \nFROM miranda'() 

Así que, por supuesto, no se encuentra la columna de id. ¿Alguna idea sobre lo que estoy haciendo mal? Gracias por adelantado.

EDIT: Conforme a lo solicitado, aquí es un ejemplo de la tabla (recuperados directamente de sqlite):

gene mature_miRNA 
---- ------------- 
80205 hsa-miR-200c 
80205 hsa-miR-200c 
9693 hsa-miR-200c 
9693 hsa-miR-200c 
9881 hsa-miR-200c 
9710 hsa-miR-200c 
9750 hsa-miR-200c 
+0

Podría publicar la tabla con datos de ejemplo favor ? – JackalopeZero

+0

Hecho: hay una muestra del tipo de datos que puede esperar ahora. – Einar

+0

ORM no funcionará sin algo que pueda servir como una identidad de fila. Considere usar la tabla directamente sin asignarla a la clase. –

Respuesta

6

Ha malinterpretado la publicación a la que hace referencia. Debe elegir una columna existente y definirla como primaria. También es posible configurar la clave primaria compuesta al ponerlos todos en definición. En su caso, creo que un gen tiene varios microARN maduros, por lo que la clave principal probablemente debería consistir en (gene_id, mature_miRNA) par. Como no hay más campos en la tabla, no es necesario marcar autoload=True.

db_table = Table("miranda", metadata, 
       Column("gene_id", Integer, primary_key=True), 
       Column("mature_miRNA", Integer, primary_key=True)) 

No sé los tipos de campos de la tabla, por lo que cambiar de manera apropiada si no son números enteros.

+0

Funciona, genial. Establecí los tipos en consecuencia y ahora obtengo los resultados correctos (en comparación con una consulta estándar usando sqlite3). – Einar

+0

De acuerdo con sus datos actualizados en la pregunta, estos pares no son únicos también, por lo que no pueden servir como clave principal. Algunas partes de ORM como consultas simples funcionan, otras pueden ser engañadas con recarga desactivada. Pero no esperes que todo funcione. –

+0

Uso principalmente igualdad e IN (es un caso de uso realmente simple), pero voy a hacer algunas pruebas precisas por las dudas. – Einar

0

Asegúrese de que la columna id existe antes que nada y después de haber intentado tanto mayúsculas y minúsculas .

También es posible establecer dos claves principales para la tabla:

Column("id", Integer, primary_key=True), 
Column("secondColumn", Integer, primary_key=True) 

Sin embargo, esto puede causar anomalías de actualización, si cualquier otra fila coincide exactamente esta fila. Tal vez sea mejor que recree la tabla e inserte su propia columna PK

+0

Puedo hacerlo, pero trataría de evitar esto, ya que proviene de un tercero y significaría bifurcar una base de datos con todos los problemas que eso conlleva. Además, ambas columnas (excepto la que intento poner en parche) tienen valores duplicados (sí, un desastre, pero yo no hice eso ...). EDITAR: Olvidé decir que la columna "id" no existe. Seguí el ejemplo vinculado en la pregunta para parchear la mesa (pero no funcionó). – Einar

0

Cambiar columna Identificación a rowid para la base de datos SQLite

originales:

db_table = Table("miranda", metadata, 
       Column("id", Integer, primary_key=True), 
       autoload=True) 

modificada:

db_table = Table("miranda", metadata, 
       Column("rowid", Integer, primary_key=True), 
       autoload=True) 
Cuestiones relacionadas