2012-02-15 4 views
5

J'utilise une base de données existante faite par un tiers avec sqlalchemy. Cependant, j'ai des problèmes car les tables n'ont pas de clés primaires et, ce qui est pire, elles ont des éléments en double pour chaque ligne, donc je ne peux pas choisir une colonne existante comme clé primaire. Les tables ont deux colonnes: les deux ont des valeurs non uniques.Python sqlalchemy: table sans clé primaire et sans doublon?

J'ai essayé de singe-patch la table par http://www.blog.pythonlibrary.org/2010/09/10/sqlalchemy-connecting-to-pre-existing-databases/ mais apparemment cela ne fonctionne pas (voir ci-dessous)

Mon code actuel est (MirnaTable est ma classe mappée, fondamentalement juste un squelette avec rien d'autre)

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

Ensuite, j'essaie par exemple l'émission

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

Et je reçois

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

Alors bien sûr, la colonne id n'est pas trouvée. Des idées sur ce que je fais mal? Merci d'avance.

EDIT: Comme l'a demandé, voici un exemple de la table (récupérée directement à partir 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

Pourriez-vous poster la table avec des données par exemple s'il vous plaît ? – JackalopeZero

+0

Fait: il existe un échantillon du type de données auquel vous pouvez vous attendre maintenant. – Einar

+0

ORM ne fonctionnera pas sans quelque chose qui peut servir d'identité de ligne. Pensez à utiliser la table directement sans la mapper en classe. –

Répondre

6

Vous avez mal interprété le poste auquel vous faites référence. Vous devez choisir une colonne existante et la définir comme primaire. Il est également possible de configurer une clé primaire composite en les mettant tous dans la définition. Dans votre cas, je pense qu'un gène a plusieurs microARN mature, de sorte que la clé primaire devrait probablement se composer de (gene_id, mature_miRNA) paire. Comme il n'y a plus de champs dans la table, il n'y a pas besoin de drapeau autoload=True. Je ne connais pas les types de champs dans votre tableau, alors changez-les de manière appropriée s'ils ne sont pas entiers.

+0

Ca marche, super. Je définis les types en conséquence et maintenant j'obtiens des résultats corrects (par rapport à une requête standard utilisant sqlite3). – Einar

+0

Selon vos données mises à jour dans la question ces paires ne sont pas uniques aussi, donc ils ne peuvent pas servir de clé primaire. Certaines parties d'ORM fonctionnent comme des requêtes simples, d'autres peuvent être trichées avec un rechargement désactivé. Mais ne vous attendez pas à ce que tout fonctionne. –

+0

J'utilise principalement l'égalité et IN (c'est un cas d'utilisation très simple), mais je vais faire quelques tests précis juste au cas où. – Einar

0

Assurez-vous que la colonne id existe d'abord et que vous avez essayé les deux majuscules et minuscules .

Il est également possible de définir deux clés primaires de la table:

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

Cependant, cela peut entraîner des anomalies de mise à jour si une autre ligne correspond exactement cette ligne. Il se peut que vous deviez recréer la table et insérer votre propre colonne PK

+0

Je peux le faire mais j'essaierais d'éviter cela, car cela vient d'une tierce partie et cela voudrait dire forger une telle base de données avec tous les problèmes qui se posent. De plus, les deux colonnes (à l'exception de celle que j'essaie d'insérer dans monkey) ont des valeurs en double (oui, un désordre, mais je n'ai pas fait ça ...). EDIT: Oublié de dire, la colonne "id" n'existe pas. J'ai suivi l'exemple lié dans la question à singe-patch la table (mais cela n'a pas fonctionné). – Einar

0

Modifier la colonne id à rowid pour la base de données SQLite

originale:

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

modifié:

db_table = Table("miranda", metadata, 
       Column("rowid", Integer, primary_key=True), 
       autoload=True) 
Questions connexes