Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does SqlAlchemy handle unique constraint in table definition

I have a table with the following declarative definition:

class Type(Base):
    __tablename__ = 'Type'
    id = Column(Integer, primary_key=True)
    name = Column(String, unique = True)
    def __init__(self, name):
        self.name = name

The column "name" has a unique constraint, but I'm able to do

type1 = Type('name1')
session.add(type1)
type2 = Type(type1.name)
session.add(type2)

So, as can be seen, the unique constraint is not checked at all, since I have added to the session 2 objects with the same name.

When I do session.commit(), I get a mysql error since the constraint is also in the mysql table.

Is it possible that sqlalchemy tells me in advance that I can not make it or identifies it and does not insert 2 entries with the same "name" columm? If not, should I keep in memory all existing names, so I can check if they exist of not, before creating the object?

like image 897
duduklein Avatar asked Apr 20 '11 11:04

duduklein


People also ask

How does SQLAlchemy handle uniqueness constraints in Python?

AFAIK, sqlalchemy does not handle uniqueness constraints in python behavior. Those "unique=True" declarations are only used to impose database level table constraints, and only then if you create the table using a sqlalchemy command, i.e. or some such.

What is a unique constraint in SQL?

A UNIQUE constraint ensures all values in a column or a group of columns are distinct from one another or unique. To define a UNIQUE constraint, you use the UNIQUE keyword followed by one or more columns. You can define a UNIQUE constraint at the column or the table level.

How to define foreign key constraints in SQLAlchemy?

In SQLAlchemy as well as in DDL, foreign key constraints can be defined as additional attributes within the table clause, or for single-column foreign keys they may optionally be specified within the definition of a single column.

Can I have more than one primary key constraint per table?

A PRIMARY KEY constraint automatically has a UNIQUE constraint. However, you can have many UNIQUE constraints per table, but only one PRIMARY KEY constraint per table. The following SQL creates a UNIQUE constraint on the "ID" column when the "Persons" table is created: SQL Server / Oracle / MS Access:


2 Answers

SQLAlechemy doesn't handle uniquness, because it's not possible to do good way. Even if you keep track of created objects and/or check whether object with such name exists there is a race condition: anybody in other process can insert a new object with the name you just checked. The only solution is to lock whole table before check and release the lock after insertion (some databases support such locking).

like image 77
Denis Otkidach Avatar answered Oct 15 '22 16:10

Denis Otkidach


AFAIK, sqlalchemy does not handle uniqueness constraints in python behavior. Those "unique=True" declarations are only used to impose database level table constraints, and only then if you create the table using a sqlalchemy command, i.e.

Type.__table__.create(engine)

or some such. If you create an SA model against an existing table that does not actually have this constraint present, it will be as if it does not exist.

Depending on your specific use case, you'll probably have to use a pattern like

try:
  existing = session.query(Type).filter_by(name='name1').one()
  # do something with existing
except:
  newobj = Type('name1')
  session.add(newobj)

or a variant, or you'll just have to catch the mysql exception and recover from there.

like image 39
acslater00 Avatar answered Oct 15 '22 16:10

acslater00