Override underlying key when using SQL ALchemy session.merge(obj) method - sqlalchemy

Is it possible to use session.merge() using a secondary key rather than the primary key for same-entity detection?
Of course, this secondary key also has a unique constraint applied to it.

Related

Expressing identifying and non-identifying relationships in MySQL

Context
I'm learning about identifying and non-identifying relationships, and I'm wondering how I'd express them in MySQL. For practice, I've been working on a database for Pokemon. For context, every few years a new version of the game comes out and updates a lot of things, e.g. the a certain move that a Pokemon can use may get stronger. This update is called generation. Moreover, each move has an elemental type, like fire or water.
So my three entities are move, generation, and type. Since I want to keep track of how a Pokemon move chances over time, a move is in an identifying relationship with generation. The name of the move is not enough to identify it, since, e.g. the move "Karate Chop" is different in generation 1 than in generation 2. So the corresponding primary key in generation, genID, should be part of my primary key for move.
On the other hand, I want to store type as a foreign key in move, but I believe this is a non-identifying relationship. Every move has a type, so I believe it's what's called a mandatory non-identifying relationship.
My attempt
So how would I write this in MySQL? I think it would be something like
CREATE TABLE move (
moveID int NOT NULL,
genID int NOT NULL,
typeID int NOT NULL,
PRIMARY KEY (MoveID, GenID),
CONSTRAINT FK_GenMove FOREIGN KEY (genID) REFERENCES generation(genID),
CONSTRAINT FK_TypeMove FOREIGN KEY (typeID) REFERENCES type(typeID)
);
However, I couldn't find an example where a foreign key was part of the primary key in the MySQL book I'm using (they discuss identifying relationships, but I couldn't find an example with syntax). Specifically, I'm unsure whether the order I list the constraints matters (should I declare my primary keys first, then my foreign keys?)
Indices
Also, I believe that my composite primary key will automatically become a clustered index for my table. A common query one would do is filtering move by generation/genID. So this should automatically be efficient since I have an index on genID, even though its part of a composite key, right? Or do I need to make a separate index for genID alone?
One thing that I realized the next day is that the order in which I declare my primary key matters. (moveID, genID) will sort by moveID first, then genID, whereas (genID, moveID) would sort the other way. Since I mentioned that I wanted the behavior of the latter case in my original post (picking out all move's in a given generation), as opposed to the former case, I felt that I should point out.

Is a primary key necessary? [duplicate]

This question already has answers here:
SQL Primary Key - is it necessary?
(5 answers)
Closed 7 years ago.
In database systems, should every table have a primary key?
For example I have a table table1(foreignkey1,foreignkey2,attribute) like this.table1 does not have a primary key.
Should I define a primary key for this table like table1id?
This is a subjective question, so I hope you don't mind me answering with some opinion :)
In the vast majority of tables I've made – I'm talking 95%+ – I've added a primary key, and been glad I did. This is either the most critical unique field in my table (think "social security number") or, more often than not, just an auto-incrementing number that allows me to quickly and easily refer to a field when querying.
This latter use is the most common, and it even has its own name: a "surrogate" or "synthetic" key. This is a value auto-generated by the database and not derived from your application data. If you want to add relations between your tables, this surrogate key is immediately helpful as a foreign key. As someone else answered, these keys are so common that MySQL likes to add one even if you don't, so I'd suggest that means the consensus is very heavily biased towards adding primary keys.
One other thing I like about primary keys is that they help convey your intent to others reading your table schemata and also to your DMBS: "this bit is how I intend to identify my rows uniquely, don't let me try to break that rule!"
To answer your question specifically: no, a primary key is not necessary. But realistically if you intend to store data in the table for any period of time beyond a few minutes, I would very strongly recommend you add one.
No, it is not required for every table to have a primary key. Whether or not a table should have a primary key is based on requirements of your database.
Even though this is allowed it is bad practice because it allows for one to add duplicate rows further preventing the unique identification of rows. Which contradicts the underline purposes of having a database.
I am a strong fan of synthetic primary keys. These are auto-incremented columns that uniquely identify each row.
These provide functionality such as:
Ability to see the order of insertion of rows. Which were inserted most recently?
Ability to create a foreign key relationship to the table. You might not need one now, but it might be useful in the future.
Ability to rename "data" columns without affecting other tables.
Presumably, for your table, you can define a primary key on (foreignkey1, foreighkey2). Composite primary keys are also sensible, but they are cumbersome for foreign key relationships and joins. And, when there are foreign key relationships, they may cause additional storage, because the composite key ends up being stored across multiple tables.
It's a good practise to have a primary key/composite primary key for a table:
it helps to join tables,
clustered tables will need primary key.
Database design should have primary key for a table.
In MySQL storage engine always creates a PRIMARY KEY if you didn't specify it explicitly, thus making an extra column you don't have access to.
You can create Composite Primary key like:
CREATE TABLE table1(
FK1 INT,
FK2 INT,
ATTRIBUTE INT,
PRIMARY KEY (FK1, FK2)
)
or create a constraint on table1:
ALTER TABLE table_name
ADD CONSTRAINT pk_table1 PRIMARY KEY (FK1,FK2)

Question about MYSQL foreign keys and orphan rows

If I add a foreign key between two tables, am I allowed to add orphan rows afterwards? Also when I'm creating a foreign key between two tables, is there any way to create it ignoring the orphan rows?
My next question is about the efficiency of foreign keys. I had always thought that they created an index between one key in a table and the corresponding key in another table which essentially made it a linear lookup when doing a join.
Is a foreign key much more efficient then simply having an index or are they the same?
Thanks.
foreign key relationship is often between a foreign key in one table and a primary key in another.
primary key do implicitly create an index.
Not foreign keys. Mostly it's good practice to add index on a foreign key column.
keys are constraints to guarantee data consistency and index can be used improve access performance on the data. So these are different things that you often combine in practices and thus are often confused.
Regarding orphan rows I think the concept of keys is to prevent this. But I'm not completely sure If I understand exactly what you are asking here. I think adding orphan rows is not possible and creating keys if orphan rows exist sounds kind of impossible.
see also other questions on SO dealing with foreign key / index topic.
Here some more good answers related to primary key / key / index

Add Primary Key to a table with existing clustered index

I have to work with a database to do reporting
The DB is quite big : 416 055 104 rows
Each row is very light though, just booleans and int ids.
Each row is identify by 3 columns, but at my surprise, there is no Primary Key on it.
Only a Clustered Index with a unique constraint.
So Knowing that, I have 2 question.
Could there be ANY good reason for that?
Is there any way I can turn this into a primary key.
Regarding question 2
Creating a new primary key also creates a non-clustered index to associate with (there is already an existing clustered one).
This is not what I am looking for. I want to keep that same index, but also make it a primary key.
Is it possible?
Would that be faster that creating the whole index again? (I hope so)
What could be the consequences? (locks? crash? corrupted data?)
There is little or no difference between a PRIMARY KEY and a UNIQUE constraint on non-nullable columns. So if the columns in question are non-nullable then I suggest you do nothing. The main reason to make a candidate key into a primary key is if you have some software (such as a data modelling tool or other development tool) that expects the key to be identified with a PRIMARY KEY constraint.
Good question.
If you already have a unique index on non nullable columns then you have a candidate key. I'm not aware of any particular benefit of making this an "official" primary key. In fact I have a feeling that not making it a PK will give greater flexibility.
A unique index can allow null
values. A primary key can't.
I believe you can't "mark" an existing index as the primary key. You'd have to drop it and recreate. To avoid stuff, I'd say it'd be good to place a TABLOCKX, HOLDLOCK on the table before doing that.

Is it possible to break a Composite key?

Is it possible to break the composite key of a table and use one of them as a primary key for other table? If yes, then please tell me how can I do it?
Generally you use a composite key when none of the columns alone contains unique values. Since a primary key must be unique, you probably can't use just one of the columns.