Renaming existing edge relationships? - orientdb

Is there a simple way to update the name of all of a type of existing edge relationships?
alter class EDGE_NAME name NEW_EDGE_NAME
updates the name of the base edge class, but doesn't affect any existing relationships.
ie:
create class Person extends V
create class Car extends V
create class OWNS extends E
create vertex Person set name="Bob"
create vertex Car set name="Jeep"
create edge OWNS from (select from Person where name="Bob") to (select from Car where name="Jeep")
alter class OWNS name DRIVES
does nothing but delete the old edge type and create a new edge type, leaving the existing relationship unaffected (Bob still OWNS a Jeep, yet OWNS doesn't exist)
What are we supposed to do if thousands of these relationships exist?

You should rename attributes with the following commands that copy to the new name and drop the previous ones for both in and out directions:
UPDATE V SET out_DRIVES = out_OWNS where out_OWNS is not null
UPDATE V SET in_DRIVES = in_OWNS where in_OWNS is not null
UPDATE V REMOVE out_OWNS where out_OWNS is not null
UPDATE V REMOVE in_OWNS where in_OWNS is not null

Related

OrientDB: What are Class Properties used for ?

I'm new to OrientDB and I understood that classes can have properties and in this case they actually act as tables in relational databases. However, I found out that even if I define properties for a class, it still doesn't guarantee that a document created from this class has a value for all its properties.
For example:
Here, I define a class 'Person' with a property 'name', and I still insert a new document to this class although it doesn't have a value for this property.
If so, what is the purpose of properties and how can I make sure that documents that do NOT include a value for a certain property will not be inserted into the class?
orientdb {db=GratefulDeadConcerts}> create class person
Class created successfully. Total classes in database now: 17.
orientdb {db=GratefulDeadConcerts}> create property person.name string
Property created successfully with id=1.
orientdb {db=GratefulDeadConcerts}> insert into person content
{"phone":"1234"}
Inserted record 'person#66:0{phone:1234} v1' in 0.000000 sec(s).
orientdb {db=GratefulDeadConcerts}> select from person
+----+-----+------+-----+
|# |#RID |#CLASS|phone|
+----+-----+------+-----+
|0 |#66:0|person|1234 |
+----+-----+------+-----+
In OrientDB you can work in schema-less, schema-hybrid or schema-full.
You can define properties and you can define constraints on each property:
http://orientdb.com/docs/last/SQL-Create-Property.html
At the same time you can define indexes on property:
http://orientdb.com/docs/last/Indexes.html
For example, if you want that a property has unique values over the entire class (a primary key), just define a unique index:
CREATE INDEX Person.name ON Person (name) UNIQUE
hope this help

Delete row from many-to-many table (VB.Net, .edmx)

I have Users and Regions. A User can be assigned to any number of Regions.
To implement this I have a table of Users, a table of Regions, and a third table UserRegion which is just UserID, RegionID (both columns form the primary key and they have foreign key relationships to the User and Region tables).
Entity Framework does not import the UserRegion table into my data model, instead it creates a property of each User object which is a list of Regions, and another on each Region object which is a list of Users. This is very useful except that I can't figure out how to un-associate a User from a Region.
The below code
Dim db as New DatabaseContext
Dim user = db.Users.Where(stuff).First()
user.Regions.Clear()
db.SaveChanges()
produces this error:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
How can get rid of the relationship rows I don't want anymore?
I figured this out.
The relationship needs to be removed from both sides. So the code should be:
user.Regions.Clear()
For Each r in db.Regions
r.Users.Remove(user)
Next
db.SaveChanges()
Now I have a zillion for loops peppering this function but oh well. Hopefully this helps someone.

Can I reference an existing row in base table from inherited one?(postgres)

I'm trying postgres, version 9.2
Can I reference an existing row in base table from inherited one?
Example:
i have a "person" table and a "student" table which inherits from person.
As i understand, if i insert new student, automatically new person is added.
But i need to insert first the person data, and then insert a reference to it and student related data.
As i understand, if i insert new student, automatically new person is added
No. Although you can select students by querying the person table, only the student table will be populated after an insert to the student table.
The relationship you want is foreign key not inheritance. Create the person id column in the student table and make it dependent on the person id on the person table.

JPA how to remove parent without delete children?

I'm trying to remove a parent, but I keep getting a Foreign Key violation. If I put Cascade.ALL in the parent, it delete the children too. And it's now what I want.
I have my parent class : Docteur
//bi-directional many-to-one association to Patient
#OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH}, orphanRemoval=false, mappedBy="docteur")
private List patients;
and my children are : Patient
I put that
#ManyToOne()
private Docteur docteur;
but in my case, the patient choul only have one Docteur.
In my Manager class. I try lot of things that didn't work
here my latest version
Clinique clinique = read(clinique_ID);
Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult();
clinique.getDocteurs().remove(docteur);
entityManager.merge(clinique);
entityManager.persist(clinique);
Here the error that I get :
Cannot delete or update a parent row: a foreign key constraint fails (jerabi_asteriskdb/Patient, CONSTRAINT FK340C82E5A10F077E FOREIGN KEY (docteur_DOCTEUR_ID) REFERENCES Docteur (DOCTEUR_ID))
You get a foreign key violation because the database checks that every docteur_id in the patient table refers to a valid docteur. This is the whole point of foreign keys. The database ensures that you don't delete a docteur still referenced by patients.
In order to delete your docteur, you must ensure that no other record in the database references this docteur_id. So, you must update all the patients of this docteur and set their docteur_id to null :
Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult();
for (Patient patient : docteur.getPatients()) {
patient.setDocteur(null);
}
docteur.patients.clear();
clinique.getDocteurs().remove(docteur);
Also, all the attached (persistent) entities are automatically updated by Hibernate. There is no need to persist and merge them. Read http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-overview.
So that a relation database can enforce data integrity, references to dependent rows in referencing tables have to be considered. SQL 2003 specifies 5 different referential actions:
CASCADE: dependent rows get deleted
RESTRICT: delete fails with an error
NO ACTION: like delete, but allows triggers to run first, in case they fix the error
SET NULL: sets the referencing columns to null (at least one column must be nullable)
SET DEFAULT: sets the referencing columns to their default value (which will then reference another existing row in the table, unless at least one default is NULL)

Composite primary keys which are also foreign keys in Entity Framework

If I have 2 tables 1 with a composite primary key where one of the keys is also a foreign key in another table:
Table 1:
A (PK, FK - maps to X in Table 2)
B (PK)
C
Table 2:
X (PK)
Y
Because A is both the PK in table 1 and FK in table 2, when I use EF to generate the entity model, I have both a Scalar AND a Navigation property for A in table 1. I cannot seem to remove A as a scalar (I think because it is a primary key).
The problem I am having is that if I create a table1Entity and set A's scalar property to a new value, A's navigation property will not be changed automatically (and vice versa).
Ideally I just want A to expose the navigation property - which is the way it behaves if A was not also part of the composite primary key anyway. Is there any way to achieve this?
Am I correct in assuming that Table1 derives from Table2? If so, I would do it like so:
(I'd also change the PK for both tables to the same name, since they probably have the same meaning - for the instance of this, I'll use the example ID)
First, create the model with the default relationships (I usually just import the two tables from the database)
In the designer, right click the base type, add inheritance, select the derived type.
Delete the one to zero or one association
Then, since the base type already has column ID, delete it from the derived type.
Go to table mapping for the derived type, and map the ID property to the ID of the table.
Well, not really. Create the view with schemabinding and create a clustered index on the view (SQL Server 2008 or later, earlier versions I'm not sure can do that). The clustered index will be recognised as a primary key, thus tricking EF(VS) into believing the view is a real table.
Have you expicity set the Ids of the composite key and referenced these in your configuration?
i.e
public class Table1
{
public Table2 A{get;set}
public int AId {get;set;}
public int BId {get;set;}
}
I assume you'll need something like:
HasKey(pc => new { pc.AId, pc.BId});
HasRequired(x => x.A).WithMany().HasForeignKey(x => x.AId);
Instead of mapping to table 1 directly, add a view to your database that's got all of table 1's fields, plus an extra copy of A (A2).
Then, map the scalar key to A2 and the nav key to A.
(You'll run into a problem where if you use a view, Visual Studio can't find a primary key; fix this by manually editing the XML of the edmx file and adding a <Key><PropertyRef ... /></Key> to the <EntityType> for table A)
I know - it's hacky and horrible... but hey - it works!