Is there a built in way / recommendation to handle duplicate entries while entities are inserted without a flush for each entry?
Lets assume we have a person entity with two fields. ID and personalNr.
ID is the primary key but personalNr has also a unique constraint.
Now i am iterating over a csv file where one personalNr can be listed in multiple rows.
If the row contains a personalNr, I check against the repository if a entry with this personalNr exist. If yes, i link the dataset to the person with the personalNr. If no, i create a new person with the personalNr and link it afterwards with the dataset.
The problem now is:
If a personalNr occurs more than once in a csv file, the dataset already exists in the entity manager when i find it again, but its unsaved to the database yet (i called no flush until now). The check against the repository will say "There is no entity in the repository" but the entity manager will throw an duplicate entry exception on flush cause it tries to create multiple entities with the same personalNr.
How to avoid this? Is the only way to save what was already inserted or not by myself? Has doctrine such a checking mechanism?
Thanks
Related
in a laravel application i use a package to import excel files to a model table.
some rows in the excel file are new, others are an update of existing models in the database. is there any way to insert the new records and update the existing records (with different values) using eloquent or the query builder.
In a nutshell you will need to pick identifiers in your spreadsheet that uniquely distinguish each row. Email for example or an ID. With those you can then query the DB to see if a given record already exists and based on that create or update.
Laravel makes this relatively easy with Eloquent's save() method which you can call against a given instantiation of a model.
save() will, assuming you set your model up correctly, decide whether a row already exists and needs updated or if it doesn't and needs created.
See here for more info: https://laravel.com/docs/5.3/eloquent#inserting-and-updating-models
I`m creating a simple data mapping system with PHP, PDO and Mysql.
One of its premises is to map arrays to entities by creating tertiary tables (not sure if the name is correct).
So, when I map an Array, I create the table with a works-for-all statement that uses the class name and method name passed, something like this:
"create table if not exists ".$tablename." (id_".$firstName." int unsigned not null, ".$secondName." ".$type.", constraint fk_".$tablename." foreign key (id_".$firstName.") references ".$firstName."(id) ".$secondReference.");"
The code is not the problem here.
What I wanted to know is if its a bad idea to TRY to create a table (if not exists) in every iteration (it does only create it for real in the first iteration of each element).
EDIT (explaining): As stated, creating inumerous tables is not the worry (wont happen), for this process is automated according to the classes (models) I`m using. The worry is if it is too costy memory and trafic-wise to check if the table exists at every iteration (this way for each item I would access the database twice, once for checking if the table exists and then again for inserting the new element into the table).
Another option would be to check if the table exists trough a select statement first, but it doesn`t seem much better.
One important information is that these methods used for mapping will olny be accessed through the objects DAO referencing each entity.
Edit: The link for the GitHub with the project is https://github.com/Sirsirious/SPDMap
to me it doesn't sound ideal to create a table each time. Might be better to reuse the same table (with an additional column as identifier between your current 'tables'
if you do create the table, don't see anything wrong with create table if not exist. this is a safe and good programming
I'd also consider using temp tables for this thing. if you create the table each time, it sounds like they are one-time usage as well. so if you don't need the data forever, temp can be a good way to go
What is the best practice to keep database integrity while using laravel's polymorphic relations?
I'm using Model Observers to update/delete related models. So for example I delete related Documents on "deleted" event while deleting a Customer.
That means if an error occurs while deleting first document the rest will stay in the database... Or if I wrap documents deleting in a transaction all of them will stay in the database while parent object is deleted...
Unfortunately, there is no good answer for that problem. You can not keep your database integrity with foreign keys because of the polymorphic relation.
One way to try is to use database triggers. As Laravel polymorphic system keep a "type" column on the table that references the related model, you could put a "before delete" trigger on tables that can be morphed to delete all occurences that references the raw you want to delete.
For example, with the structure used in Laravel documentation :
staff
id - integer
name - string
orders
id - integer
price - integer
photos
id - integer
path - string
imageable_id - integer
imageable_type - string
You can put an "before delete" trigger on staff table that executes a query (PostgreSQL syntax here) like that :
DELETE FROM photos WHERE imageable_id = OLD.id AND imageable_type = 'staff'
That way, each time you delete a staff raw, all referenced photos will be deleted in the same transaction.
I really don't know if it's the best way to keep integrity with this kind of relation, but it seems to be an efficient one.
I am inserting the Food(table) keys/enteries into the DB and I get duplicate keys even though I am not suppose to based on the manual. I am really confused and stuck!?
Relationship is as follows: every user has a related to many different food types. Then whenever I read the user's $data['food'] agin...It creates a duplicate entry . Meaning that next time the user logs in instead of knowing that food exits. it increments the primary key and does not understand that the key exits contrary to what manual suggest that save is smart enough to know that...So my problem is I want to have only one copy of every entry but I end up with more entries. How Can I avoid having duplicate entries ?
for(i=0; sizof($data['food']);i++){
$f=new Food();
$f->food_id=$food['id'];
$f->name=$food[$j]['name'];
$f->user_id=$food_id;
$u=new User();
$u->where('user_id',$food)->get();
//save food and the relationship
$fm->save($f);
}
Why did you set your user_id to be the same as food_id?
The code you wrote to get the user details, doesn't seem to be doing anything too.
quick question.
In my user database I have 5 separate tables all containing different information. 4 tables are connected by foreign key to the primary key of the first table.
I am wanting to trigger row inserts on the other 4 tables when I do an insert on the first (primary). I thought that with ON UPDATE CASCADE would do this for me but after trying it I realised it did not...I know clue is in the name ON UPDATE!!!!!
I also tried and failed at multiple triggers on the same table but found this was not possible either.
What I am planning on doing is putting a trigger on the first to INSERT on the second and then putting a trigger on the second to insert on the third......etc
Would just like to know if this is a wise thing to do or not or if I am missing a better and simpler way of doing this.
Any help/advice much appreciated.
Based on the given information, it "feels" as if there might be a flaw in the database design if each of the child tables requires a row for every single row in the parent table. There is a reason that "ON INSERT CASCADE" does not exist; it is typically not considered meaningful.
The first thought that comes to mind is that the child tables should actually be part of the parent table; it sounds as if there is a one-to-one relationship. It still may make sense to have separate tables from an organizational standpoint (and size of records), but it is something to think about.
If there is not a one-to-one relationship, then the ability to add meaningful data beyond default values to the child tables would imply there might be a bit more normalization of data required. If the only values to be added are NULLs, then one could maybe argue that there is no real point in having the record because a LEFT JOIN could produce the same results without that record.
Having said all that, if it is required, I would think that it would be better to have a single trigger on the parent table add all the records to the child tables rather than chain them in several triggers. That way the logic would be contained in a single location.
Not understanding your structure (the information you need in each of these tables is pertinent to correctly answer), I can only guess that a trigger might not be what you want to do this. If your tables have other fields beyond what is in table 1 and they do not have default values, how will you get the value for those other fields inthe trigger? Personally I would use a stored proc to insert to table1 and get the id value back from the insert and then insert to the other tables with the additonal information needed and put it all in a transaction so that if one insert fails all are rolled back.