Database joining table in geodjango - database

I created a model class Parcel:
from django.db import models
from django.contrib.gis.db import models as gismodels
class Parcel(gismodels.Model):
new_pin = models.CharField(max_length=32)
geometry = gismodels.PolygonField(srid=32651)
objects = gismodels.GeoManager()
def __unicode__(self):
return self.new_pin`
Now, I want these model to have a joined query in other table(property), but these table(property) already existed in the database. Anybody knows how to implement it in python-geodjango?? Eventhough table(property) does not declared in my model.??How can I do it??
This is now the query I would like to display..
query in sql: (select t2.land_classification from table1 t1, table2 t2 where t1.new_pin = t2.new_pin group by t2.land_classification)
NOTE: Table 1 is the Parcel model above.
Table 2 is the existed table in the database.

Related

Peewee join query can't get data

I have the following 2 tables in my database.
tbl_customers
cid (int auto)
name (text)
tbl_contacts
cid
email
name
phone
I am trying to write the following sql query in peewee, but just can't get it to work
SELECT tbl_customers.cid, tbl_contacts.name
FROM tbl_customers
INNER JOIN tbl_contacts ON tbl_customers.cid = tbl_contacts.cid
WHERE tbl_customers.cid = '5';
I am trying to get the data to display like this
tbl_customer.cid = 5
tbl_contacts.name = 'Test User'
I tried the following in peewee, based on google searches that i am finding.
tbl_customers.select(tbl_customers.cid, tbl_contacts.name).join(tbl_contacts, on=(tbl_customers.cid == tbl_contacts.cid)).where(tbl_customers.cid == '5')
Peewee automatically puts your models into a graph, so the contact name would be accessed something like:
customer.contact.name
If you just want all data on a single model instance, you can append ".objects()" to your query and it will put all the column data on the instance-type being selected.
This is documented thoroughly:
http://docs.peewee-orm.com/en/latest/peewee/relationships.html#selecting-from-multiple-sources

Database Model Design With Laravel Eloquent

we have a problem to query our database in a meant-to-be fashion:
Tables:
employees <1-n> employee_card_validity <n-1> card <1-n> stamptimes
id id id id
employee_id no card_id
card_id timestamp
valid_from
valid_to
Employee is mapped onto Card via the EmployeeCardValidity Pivot which has additional attributes.
We reuse cards which means that a card has multiple entries in the pivot table. Which card is right is determined by valid_from/valid_to. These attributes are constrained not to overlap. Like that there's always a unique relationship from employee to stamptimes where an Employee can have multiple cards and a card can belong to multiple Employees over time.
Where we fail is to define a custom relationship from Employee to Stamptimes which regards which Stamptimes belong to an Employee. That means when I fetch a Stamptime its timestamp is distinctly assigned to a Card because it's inside its valid_from and valid_to.
But I cannot define an appropriate relation that gives me all Stamptimes for a given Employee. The only thing I have so far is to define a static field in Employee and use that to limit the relationship to only fetch Stamptimes of the given time.
public static $date = '';
public function cardsX() {
return $this->belongsToMany('App\Models\Tempos\Card', 'employee_card_validity',
'employee_id', 'card_id')
->wherePivot('valid_from', '>', self::$date);
}
Then I would say in the Controller:
\App\Models\Tempos\Employee::$date = '2020-01-20 00:00:00';
$ags = DepartmentGroup::with(['departments.employees.cardsX.stamptimes'])
But I cannot do that dynamically depending on the actual query result as you could with sql:
SELECT ecv.card_id, employee_id, valid_from, valid_to, s.timestamp
FROM staff.employee_card_validity ecv
join staff.stamptimes s on s.card_id = ecv.card_id
and s.stamptimes between valid_from and coalesce(valid_to , 'infinity'::timestamp)
where employee_id = ?
So my question is: is that database desing unusual or is an ORM mapper just not capable of describing such relationships. Do I have to fall back to QueryBuilder/SQL in such cases?
Do you suit your database model towards ORM or the other way?
You can try:
DB::query()->selectRaw('*')->from('employee_card_validity')
->join('stamptimes', function($join) {
return $join->on('employee_card_validity.card_id', '=', 'stamptimes.card_id')
->whereRaw('stamptimes.timestamp between employee_card_validity.valid_from and employee_card_validity.valid_to');
})->where('employee_id', ?)->get();
If your Laravel is x > 5.5, you can initiate Model extends the Pivot class I believe, so:
EmployeeCardValidity::join('stamptimes', function($join) {
return $join->on('employee_card_validity.card_id', '=', 'stamptimes.card_id')
->whereRaw('stamptimes.timestamp between employee_card_validity.valid_from and employee_card_validity.valid_to');
})->where('employee_id', ?)->get();
But code above is only translating your sql query, I believe I can write better if I know exactly your use cases.

Can we query multiple tables across multiple oracle users and tabularize the rows in Django's Admin UI

Basically, I have issues working with a legacy database where the tables I am using have no proper referential integrity (like no foreign keys; just tables but 'I' know they are related by some columns). So, Django's framework would not be beneficial while querying n tables across m different oracle users.
Something like this:
select t1.col1, t2.col3, t3.col2 from user1.table1 t1, user2.table2 t2, user3.table3 t3 where t1.col1 = t2.col2 AND t2.col2 = t3.col3;
And now in Django's Admin UI, I wanted to display this:
---------------------------
| col1 | col3 | col2 |
---------------------------
| abcd | defg | hijk |
---------------------------
| 1234 | 5678 | 9009 |
---------------------------
I have started on Django for its fast development only very recently. Hence, any support or docs are much appreciated.
To take advantage of Django Admin, you need to make a model first, no matter from where it fetches data.
Now, since we are mapping the model to DB, you could either make the model based on a DB view, or any one of the three tables(user1.table1, user2.table2 and user3.table3):
Base on DB view:
First, create a DB view to take col1, col2 and col3 from tables.
Also, choose a primary key for the model: it could be any (including extra) column in the DB view, as long as the model field w/ primary_key=True matches the column, here I simply choose col1.
# use Sqlite to create view, Oracle could be similar
CREATE VIEW view_for_legacy_tables AS SELECT t1.col1, t2.col3, t3.col2 from user1.table1 t1, user2.table2 t2, user3.table3 t3 where t1.col1 = t2.col2 AND t2.col2 = t3.col3;
# in model
class Foo(models.Model):
col1 = models.TextField(primary_key=True)
col2 = models.TextField()
col3 = models.TextField()
class Meta:
db_table = 'view_for_legacy_tables'
From now on, syncdb or South migrate might complain the exists, here simply ignore them.
You could bypass it by faking migration in South or move the model from models.py to other files or functions that does not loaded by models.py.
After define corresponding ModelAdmin for the model Foo, the Foo could be displayed in changelist in Django Admin.
If you want to use addview or changeview to do some modification upon the tables, you could override save method of the Foo model or customize ModelForm, or customize add_view/change_view of the ModelAdmin. The code varies on your actual usage, thus I don't provide one here.
Base on table user1.table1
This works similar as the method based on DB view. To be able to use addview and changeview, you need to customize ModelForm also.
Define the model
class Foo(models.Model):
col1 = models.TextField(primary_key=True)
class Meta:
db_table = 'user1.table1'
Then in admin.py
class FooAdmin(admin.ModelAdmin):
list_display = ('col1', 'col2', 'col3')
def queryset(self, request): # you could customize the default manager of model Foo
qs = super(FooAdmin, self).queryset(request)
return qs.extra(select={'col2':'user2.table2.col2', 'col3':'user3.table3.col3'},
tables=['user2.table2', 'user3.table3'],
where=['col1 = user2.table2.col2', 'user2.table2.col2'='user3.table3.col3']) # or use `raw()`, depends on your columns
def col2(self, obj):
return obj.col2
def col3(self, obj):
return obj.col3
update
The usage is very uncommon, thus I've seen few documents about it. Most relative things could be options.py inside django/contrib/admin and the implementation of Model inside django/db/models/base.py.
If you want to achieve SELECT * from t1, t2, t3 where ... like '%?%'", [var1]), the easiest way probably is to write your own view by using Admin UI, just as https://github.com/dmpayton/django-mongoadmin
If var1 of SELECT * from t1, t2, t3 where ... like '%?%'", [var1]) is determined, you could make several models for each value of var1; if its not, you have to do some dynamic way about model and admin, just ref Django dynamic model fields , which could be even harder IMO.

Creating relationships in Microsoft Access

I'm creating a database to track my students' participation in classes. This is what I've set up so far. I'm working in Access 2007.
Participant Master table - name, contact info, enrolled class, enrolled semester. Enrolled class (Class A, Class B, Class C) and enrolled semester (Semester 1, Semester 2) are defined in tables. Primary key is an autoincrement number but students all get a school ID number (ParticipantID).
Query1 pulls name & address for students enrolled in class A, semester 2
(SELECT name, address FROM ParticipantMaster WHERE EnrClass = "Class A" and EnrSem = "Semester 2"). The query works.
DailySessionLog is a table to represent each daily class. Includes fields for date, instructor name (check from list), discusssion topic (check from list).
Now I want to link DailySessionLog to Query1 -- letting me check off every day whether a student was there for None, Partial, Half, or Full session that day. I'm having trouble linking these and creating a subform. Any help?
I tried having a ParticipantID field in DailySessionLog which I linked to ParticipantID in Query1. It doesn't recognize if it's a one:one or :many relationship. If I go ahead and create a subform using the Access wizard it treats the Participant data as the "higher" form and the DailySessionLog data as the "sub" form. I want it to be the other way around.
Thanks for helping!
To create a one-to-one or one-to-many relationship, you should link DailySessionLog to ParticipantMaster rather than to Query1. You would then create a query to show the daily session logs of a given class for a given semester. Example:
SELECT {field list} FROM ParticipantMaster INNER JOIN DailySessionLog ON {join expression} WHERE ParticipantMaster.EnrClass = "Class A" AND ParticipantMaster.EnrSem = "Semester 2"
However, it would be better to use variable parameters rather than hard-coded strings. Example:
SELECT {field list} FROM ParticipantMaster INNER JOIN DailySessionLog ON {join expression} WHERE ParticipantMaster.EnrClass = [ClassName] AND ParticipantMaster.EnrSem = [SemesterName]
Or, to use a value from a control on an open form:
SELECT {field list} FROM ParticipantMaster INNER JOIN DailySessionLog ON {join expression} WHERE ParticipantMaster.EnrClass = [Forms]![FormName]![ClassControlName] AND ParticipantMaster.EnrSem = [Forms]![FormName]![SemesterControlName]
EDIT
Actually, you want to use this AND xQbert's idea, so, with table names like this for brevity:
Participants (a.k.a. ParticipantMaster)
Sessions (a.k.a DailySessionLog)
ParticipantSession (a.k.a. Participant_daily_session_log)
the first query would be more like this:
SELECT {field list}
FROM
Participants
INNER JOIN ParticipantSession ON Participant.ID = ParticipantSession.ParticipantID
INNER JOIN Sessions ON ParticipantSession.SessionID = Session.ID
Where do you intend the database to "Store" the participation?
I think the problem is you need another table: a Particpiant_Daily_sessioN_log which would store the results of your daily log for each student participation.
Think about the table dailysessionlog you don't want instructor name, topic and date listed for EACH student do you?
So what you have is a many students may attend class and a class may have many students. This means you have a many to many which needs to be resolved before access can figure out what you want to do.
Think of the following tables:
Participant (ParticipantID)
Class (ClassID)
Session (SessionID, ClassID)
ClassParticipants (ClassId, ParticipantID, Semester, year
SessionParticipants (SessionID, ClassID, ParticipantID)

Need to order by properties in the reference property, any good solution?

Say I have 2 kind:
class Account(db.Model):
name = db.StringProperty()
create_time = db.DataTimeProperty()
last_login = db.DateTimeProperty()
last_update = db.DataTimeProperty()
class Relationship(db.Model)
owner = db.ReferenceProperty(Account)
target = db.ReferenceProperty(Account)
type = db.IntegerProperty()
I want to get the equivalence of following query:
SELECT target
FROM Relationship
WHERE owner = :key AND type = :type
ORDERBY target.last_login DESC
How to do that?
reference: http://www.mail-archive.com/google-appengine#googlegroups.com/msg15878.html
There's no equivalent for that query in datastore. Some points:
You can't select a single property. SELECT is always SELECT * (you select a whole entity).
You can't do joins. You need to denormalize your models to fit the queries you will perform, or perform multiple queries.
So to achieve your goal, you need to have last_login stored in Relationship, or have a 3rd model to serve as index for that specific query.

Resources